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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '5.19-rc-smb3-client-fixes-updated' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs client updates from Steve French:

- multichannel fixes to improve reconnect after network failure

- improved caching of root directory contents (extending benefit of
directory leases)

- two DFS fixes

- three fixes for improved debugging

- an NTLMSSP fix for mounts t0 older servers

- new mount parm to allow disabling creating sparse files

- various cleanup fixes and minor fixes pointed out by coverity

* tag '5.19-rc-smb3-client-fixes-updated' of git://git.samba.org/sfrench/cifs-2.6: (24 commits)
smb3: remove unneeded null check in cifs_readdir
cifs: fix ntlmssp on old servers
cifs: cache the dirents for entries in a cached directory
cifs: avoid parallel session setups on same channel
cifs: use new enum for ses_status
cifs: do not use tcpStatus after negotiate completes
smb3: add mount parm nosparse
smb3: don't set rc when used and unneeded in query_info_compound
smb3: check for null tcon
cifs: fix minor compile warning
Add various fsctl structs
Add defines for various newer FSCTLs
smb3: add trace point for oplock not found
cifs: return the more nuanced writeback error on close()
smb3: add trace point for lease not found issue
cifs: smbd: fix typo in comment
cifs: set the CREATE_NOT_FILE when opening the directory in use_cached_dir()
cifs: check for smb1 in open_cached_dir()
cifs: move definition of cifs_fattr earlier in cifsglob.h
cifs: print TIDs as hex
...

+559 -189
+8 -3
fs/cifs/cifs_debug.c
··· 116 116 tcon->ses->server->ops->dump_share_caps(m, tcon); 117 117 if (tcon->use_witness) 118 118 seq_puts(m, " Witness"); 119 - 119 + if (tcon->broken_sparse_sup) 120 + seq_puts(m, " nosparse"); 120 121 if (tcon->need_reconnect) 121 122 seq_puts(m, "\tDISCONNECTED "); 122 123 seq_putc(m, '\n'); ··· 387 386 (ses->serverNOS == NULL)) { 388 387 seq_printf(m, "\n\t%d) Address: %s Uses: %d Capability: 0x%x\tSession Status: %d ", 389 388 i, ses->ip_addr, ses->ses_count, 390 - ses->capabilities, ses->status); 389 + ses->capabilities, ses->ses_status); 391 390 if (ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST) 392 391 seq_printf(m, "Guest "); 393 392 else if (ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) ··· 399 398 "\n\tSMB session status: %d ", 400 399 i, ses->ip_addr, ses->serverDomain, 401 400 ses->ses_count, ses->serverOS, ses->serverNOS, 402 - ses->capabilities, ses->status); 401 + ses->capabilities, ses->ses_status); 403 402 } 404 403 405 404 seq_printf(m, "\n\tSecurity type: %s ", ··· 419 418 spin_lock(&ses->chan_lock); 420 419 if (CIFS_CHAN_NEEDS_RECONNECT(ses, 0)) 421 420 seq_puts(m, "\tPrimary channel: DISCONNECTED "); 421 + if (CIFS_CHAN_IN_RECONNECT(ses, 0)) 422 + seq_puts(m, "\t[RECONNECTING] "); 422 423 423 424 if (ses->chan_count > 1) { 424 425 seq_printf(m, "\n\n\tExtra Channels: %zu ", ··· 429 426 cifs_dump_channel(m, j, &ses->chans[j]); 430 427 if (CIFS_CHAN_NEEDS_RECONNECT(ses, j)) 431 428 seq_puts(m, "\tDISCONNECTED "); 429 + if (CIFS_CHAN_IN_RECONNECT(ses, j)) 430 + seq_puts(m, "\t[RECONNECTING] "); 432 431 } 433 432 } 434 433 spin_unlock(&ses->chan_lock);
+2
fs/cifs/cifsfs.c
··· 582 582 seq_puts(s, ",nocase"); 583 583 if (tcon->nodelete) 584 584 seq_puts(s, ",nodelete"); 585 + if (cifs_sb->ctx->no_sparse) 586 + seq_puts(s, ",nosparse"); 585 587 if (tcon->local_lease) 586 588 seq_puts(s, ",locallease"); 587 589 if (tcon->retry)
+88 -36
fs/cifs/cifsglob.h
··· 106 106 * CIFS vfs client Status information (based on what we know.) 107 107 */ 108 108 109 - /* associated with each tcp and smb session */ 109 + /* associated with each connection */ 110 110 enum statusEnum { 111 111 CifsNew = 0, 112 112 CifsGood, ··· 114 114 CifsNeedReconnect, 115 115 CifsNeedNegotiate, 116 116 CifsInNegotiate, 117 - CifsNeedSessSetup, 118 - CifsInSessSetup, 117 + }; 118 + 119 + /* associated with each smb session */ 120 + enum ses_status_enum { 121 + SES_NEW = 0, 122 + SES_GOOD, 123 + SES_EXITING, 124 + SES_NEED_RECON, 125 + SES_IN_SETUP 119 126 }; 120 127 121 128 /* associated with each tree connection to the server */ ··· 922 915 }; 923 916 924 917 struct cifs_chan { 918 + unsigned int in_reconnect : 1; /* if session setup in progress for this channel */ 925 919 struct TCP_Server_Info *server; 926 920 __u8 signkey[SMB3_SIGN_KEY_SIZE]; 927 921 }; ··· 938 930 struct mutex session_mutex; 939 931 struct TCP_Server_Info *server; /* pointer to server info */ 940 932 int ses_count; /* reference counter */ 941 - enum statusEnum status; /* updates protected by cifs_tcp_ses_lock */ 933 + enum ses_status_enum ses_status; /* updates protected by cifs_tcp_ses_lock */ 942 934 unsigned overrideSecFlg; /* if non-zero override global sec flags */ 943 935 char *serverOS; /* name of operating system underlying server */ 944 936 char *serverNOS; /* name of network operating system of server */ ··· 952 944 and after mount option parsing we fill it */ 953 945 char *domainName; 954 946 char *password; 955 - char *workstation_name; 947 + char workstation_name[CIFS_MAX_WORKSTATION_LEN]; 956 948 struct session_key auth_key; 957 949 struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */ 958 950 enum securityEnum sectype; /* what security flavor was specified? */ ··· 985 977 #define CIFS_MAX_CHANNELS 16 986 978 #define CIFS_ALL_CHANNELS_SET(ses) \ 987 979 ((1UL << (ses)->chan_count) - 1) 980 + #define CIFS_ALL_CHANS_GOOD(ses) \ 981 + (!(ses)->chans_need_reconnect) 988 982 #define CIFS_ALL_CHANS_NEED_RECONNECT(ses) \ 989 983 ((ses)->chans_need_reconnect == CIFS_ALL_CHANNELS_SET(ses)) 990 984 #define CIFS_SET_ALL_CHANS_NEED_RECONNECT(ses) \ 991 985 ((ses)->chans_need_reconnect = CIFS_ALL_CHANNELS_SET(ses)) 992 986 #define CIFS_CHAN_NEEDS_RECONNECT(ses, index) \ 993 987 test_bit((index), &(ses)->chans_need_reconnect) 988 + #define CIFS_CHAN_IN_RECONNECT(ses, index) \ 989 + ((ses)->chans[(index)].in_reconnect) 994 990 995 991 struct cifs_chan chans[CIFS_MAX_CHANNELS]; 996 992 size_t chan_count; ··· 1021 1009 return ses->server->vals->cap_unix & ses->capabilities; 1022 1010 } 1023 1011 1012 + /* 1013 + * common struct for holding inode info when searching for or updating an 1014 + * inode with new info 1015 + */ 1016 + 1017 + #define CIFS_FATTR_DFS_REFERRAL 0x1 1018 + #define CIFS_FATTR_DELETE_PENDING 0x2 1019 + #define CIFS_FATTR_NEED_REVAL 0x4 1020 + #define CIFS_FATTR_INO_COLLISION 0x8 1021 + #define CIFS_FATTR_UNKNOWN_NLINK 0x10 1022 + #define CIFS_FATTR_FAKE_ROOT_INO 0x20 1023 + 1024 + struct cifs_fattr { 1025 + u32 cf_flags; 1026 + u32 cf_cifsattrs; 1027 + u64 cf_uniqueid; 1028 + u64 cf_eof; 1029 + u64 cf_bytes; 1030 + u64 cf_createtime; 1031 + kuid_t cf_uid; 1032 + kgid_t cf_gid; 1033 + umode_t cf_mode; 1034 + dev_t cf_rdev; 1035 + unsigned int cf_nlink; 1036 + unsigned int cf_dtype; 1037 + struct timespec64 cf_atime; 1038 + struct timespec64 cf_mtime; 1039 + struct timespec64 cf_ctime; 1040 + u32 cf_cifstag; 1041 + }; 1042 + 1043 + struct cached_dirent { 1044 + struct list_head entry; 1045 + char *name; 1046 + int namelen; 1047 + loff_t pos; 1048 + 1049 + struct cifs_fattr fattr; 1050 + }; 1051 + 1052 + struct cached_dirents { 1053 + bool is_valid:1; 1054 + bool is_failed:1; 1055 + struct dir_context *ctx; /* 1056 + * Only used to make sure we only take entries 1057 + * from a single context. Never dereferenced. 1058 + */ 1059 + struct mutex de_mutex; 1060 + int pos; /* Expected ctx->pos */ 1061 + struct list_head entries; 1062 + }; 1063 + 1024 1064 struct cached_fid { 1025 1065 bool is_valid:1; /* Do we have a useable root fid */ 1026 1066 bool file_all_info_is_valid:1; ··· 1085 1021 struct dentry *dentry; 1086 1022 struct work_struct lease_break; 1087 1023 struct smb2_file_all_info file_all_info; 1024 + struct cached_dirents dirents; 1088 1025 }; 1089 1026 1090 1027 /* ··· 1706 1641 struct cifsFileInfo *cfile; 1707 1642 }; 1708 1643 1709 - /* 1710 - * common struct for holding inode info when searching for or updating an 1711 - * inode with new info 1712 - */ 1713 - 1714 - #define CIFS_FATTR_DFS_REFERRAL 0x1 1715 - #define CIFS_FATTR_DELETE_PENDING 0x2 1716 - #define CIFS_FATTR_NEED_REVAL 0x4 1717 - #define CIFS_FATTR_INO_COLLISION 0x8 1718 - #define CIFS_FATTR_UNKNOWN_NLINK 0x10 1719 - #define CIFS_FATTR_FAKE_ROOT_INO 0x20 1720 - 1721 - struct cifs_fattr { 1722 - u32 cf_flags; 1723 - u32 cf_cifsattrs; 1724 - u64 cf_uniqueid; 1725 - u64 cf_eof; 1726 - u64 cf_bytes; 1727 - u64 cf_createtime; 1728 - kuid_t cf_uid; 1729 - kgid_t cf_gid; 1730 - umode_t cf_mode; 1731 - dev_t cf_rdev; 1732 - unsigned int cf_nlink; 1733 - unsigned int cf_dtype; 1734 - struct timespec64 cf_atime; 1735 - struct timespec64 cf_mtime; 1736 - struct timespec64 cf_ctime; 1737 - u32 cf_cifstag; 1738 - }; 1739 - 1740 1644 static inline void free_dfs_info_param(struct dfs_info3_param *param) 1741 1645 { 1742 1646 if (param) { ··· 2011 1977 * MS-DFSC 2.2.4 RESP_GET_DFS_REFERRAL. 2012 1978 */ 2013 1979 return is_tcon_dfs(tcon) || (ref && (ref->flags & DFSREF_REFERRAL_SERVER)); 1980 + } 1981 + 1982 + static inline u64 cifs_flock_len(struct file_lock *fl) 1983 + { 1984 + return fl->fl_end == OFFSET_MAX ? 0 : fl->fl_end - fl->fl_start + 1; 1985 + } 1986 + 1987 + static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses) 1988 + { 1989 + if (WARN_ON_ONCE(!ses || !ses->server)) 1990 + return 0; 1991 + /* 1992 + * Make workstation name no more than 15 chars when using insecure dialects as some legacy 1993 + * servers do require it during NTLMSSP. 1994 + */ 1995 + if (ses->server->dialect <= SMB20_PROT_ID) 1996 + return min_t(size_t, sizeof(ses->workstation_name), RFC1001_NAME_LEN_WITH_NULL); 1997 + return sizeof(ses->workstation_name); 2014 1998 } 2015 1999 2016 2000 #endif /* _CIFS_GLOB_H */
+9
fs/cifs/cifsproto.h
··· 619 619 cifs_ses_get_chan_index(struct cifs_ses *ses, 620 620 struct TCP_Server_Info *server); 621 621 void 622 + cifs_chan_set_in_reconnect(struct cifs_ses *ses, 623 + struct TCP_Server_Info *server); 624 + void 625 + cifs_chan_clear_in_reconnect(struct cifs_ses *ses, 626 + struct TCP_Server_Info *server); 627 + bool 628 + cifs_chan_in_reconnect(struct cifs_ses *ses, 629 + struct TCP_Server_Info *server); 630 + void 622 631 cifs_chan_set_need_reconnect(struct cifs_ses *ses, 623 632 struct TCP_Server_Info *server); 624 633 void
+3 -2
fs/cifs/cifssmb.c
··· 75 75 76 76 /* only send once per connect */ 77 77 spin_lock(&cifs_tcp_ses_lock); 78 - if ((tcon->ses->status != CifsGood) || (tcon->status != TID_NEED_RECON)) { 78 + if ((tcon->ses->ses_status != SES_GOOD) || (tcon->status != TID_NEED_RECON)) { 79 79 spin_unlock(&cifs_tcp_ses_lock); 80 80 return; 81 81 } ··· 2558 2558 2559 2559 pLockData->fl_start = le64_to_cpu(parm_data->start); 2560 2560 pLockData->fl_end = pLockData->fl_start + 2561 - le64_to_cpu(parm_data->length) - 1; 2561 + (le64_to_cpu(parm_data->length) ? 2562 + le64_to_cpu(parm_data->length) - 1 : 0); 2562 2563 pLockData->fl_pid = -le32_to_cpu(parm_data->pid); 2563 2564 } 2564 2565 }
+59 -48
fs/cifs/connect.c
··· 241 241 if (!mark_smb_session && !CIFS_ALL_CHANS_NEED_RECONNECT(ses)) 242 242 goto next_session; 243 243 244 - ses->status = CifsNeedReconnect; 244 + ses->ses_status = SES_NEED_RECON; 245 245 246 246 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { 247 247 tcon->need_reconnect = true; ··· 1789 1789 goto out; 1790 1790 } 1791 1791 1792 - cifs_dbg(FYI, "IPC tcon rc = %d ipc tid = %d\n", rc, tcon->tid); 1792 + cifs_dbg(FYI, "IPC tcon rc=%d ipc tid=0x%x\n", rc, tcon->tid); 1793 1793 1794 1794 ses->tcon_ipc = tcon; 1795 1795 out: ··· 1828 1828 1829 1829 spin_lock(&cifs_tcp_ses_lock); 1830 1830 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { 1831 - if (ses->status == CifsExiting) 1831 + if (ses->ses_status == SES_EXITING) 1832 1832 continue; 1833 1833 if (!match_session(ses, ctx)) 1834 1834 continue; ··· 1848 1848 cifs_dbg(FYI, "%s: ses_count=%d\n", __func__, ses->ses_count); 1849 1849 1850 1850 spin_lock(&cifs_tcp_ses_lock); 1851 - if (ses->status == CifsExiting) { 1851 + if (ses->ses_status == SES_EXITING) { 1852 1852 spin_unlock(&cifs_tcp_ses_lock); 1853 1853 return; 1854 1854 } ··· 1864 1864 /* ses_count can never go negative */ 1865 1865 WARN_ON(ses->ses_count < 0); 1866 1866 1867 - if (ses->status == CifsGood) 1868 - ses->status = CifsExiting; 1867 + if (ses->ses_status == SES_GOOD) 1868 + ses->ses_status = SES_EXITING; 1869 1869 spin_unlock(&cifs_tcp_ses_lock); 1870 1870 1871 1871 cifs_free_ipc(ses); 1872 1872 1873 - if (ses->status == CifsExiting && server->ops->logoff) { 1873 + if (ses->ses_status == SES_EXITING && server->ops->logoff) { 1874 1874 xid = get_xid(); 1875 1875 rc = server->ops->logoff(xid, ses); 1876 1876 if (rc) ··· 2037 2037 } 2038 2038 } 2039 2039 2040 - ctx->workstation_name = kstrdup(ses->workstation_name, GFP_KERNEL); 2041 - if (!ctx->workstation_name) { 2042 - cifs_dbg(FYI, "Unable to allocate memory for workstation_name\n"); 2043 - rc = -ENOMEM; 2044 - kfree(ctx->username); 2045 - ctx->username = NULL; 2046 - kfree_sensitive(ctx->password); 2047 - ctx->password = NULL; 2048 - kfree(ctx->domainname); 2049 - ctx->domainname = NULL; 2050 - goto out_key_put; 2051 - } 2040 + strscpy(ctx->workstation_name, ses->workstation_name, sizeof(ctx->workstation_name)); 2052 2041 2053 2042 out_key_put: 2054 2043 up_read(&key->sem); ··· 2079 2090 ses = cifs_find_smb_ses(server, ctx); 2080 2091 if (ses) { 2081 2092 cifs_dbg(FYI, "Existing smb sess found (status=%d)\n", 2082 - ses->status); 2093 + ses->ses_status); 2083 2094 2084 2095 spin_lock(&ses->chan_lock); 2085 2096 if (cifs_chan_needs_reconnect(ses, server)) { ··· 2146 2157 if (!ses->domainName) 2147 2158 goto get_ses_fail; 2148 2159 } 2149 - if (ctx->workstation_name) { 2150 - ses->workstation_name = kstrdup(ctx->workstation_name, 2151 - GFP_KERNEL); 2152 - if (!ses->workstation_name) 2153 - goto get_ses_fail; 2154 - } 2160 + 2161 + strscpy(ses->workstation_name, ctx->workstation_name, sizeof(ses->workstation_name)); 2162 + 2155 2163 if (ctx->domainauto) 2156 2164 ses->domainAuto = ctx->domainauto; 2157 2165 ses->cred_uid = ctx->cred_uid; ··· 2495 2509 */ 2496 2510 tcon->retry = ctx->retry; 2497 2511 tcon->nocase = ctx->nocase; 2512 + tcon->broken_sparse_sup = ctx->no_sparse; 2498 2513 if (ses->server->capabilities & SMB2_GLOBAL_CAP_DIRECTORY_LEASING) 2499 2514 tcon->nohandlecache = ctx->nohandlecache; 2500 2515 else ··· 3407 3420 } 3408 3421 3409 3422 /* 3410 - * Check if path is remote (e.g. a DFS share). Return -EREMOTE if it is, 3411 - * otherwise 0. 3423 + * Check if path is remote (i.e. a DFS share). 3424 + * 3425 + * Return -EREMOTE if it is, otherwise 0 or -errno. 3412 3426 */ 3413 3427 static int is_path_remote(struct mount_ctx *mnt_ctx) 3414 3428 { ··· 3420 3432 struct cifs_tcon *tcon = mnt_ctx->tcon; 3421 3433 struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; 3422 3434 char *full_path; 3435 + #ifdef CONFIG_CIFS_DFS_UPCALL 3436 + bool nodfs = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS; 3437 + #endif 3423 3438 3424 3439 if (!server->ops->is_path_accessible) 3425 3440 return -EOPNOTSUPP; ··· 3440 3449 rc = server->ops->is_path_accessible(xid, tcon, cifs_sb, 3441 3450 full_path); 3442 3451 #ifdef CONFIG_CIFS_DFS_UPCALL 3452 + if (nodfs) { 3453 + if (rc == -EREMOTE) 3454 + rc = -EOPNOTSUPP; 3455 + goto out; 3456 + } 3457 + 3458 + /* path *might* exist with non-ASCII characters in DFS root 3459 + * try again with full path (only if nodfs is not set) */ 3443 3460 if (rc == -ENOENT && is_tcon_dfs(tcon)) 3444 3461 rc = cifs_dfs_query_info_nonascii_quirk(xid, tcon, cifs_sb, 3445 3462 full_path); 3446 3463 #endif 3447 - if (rc != 0 && rc != -EREMOTE) { 3448 - kfree(full_path); 3449 - return rc; 3450 - } 3464 + if (rc != 0 && rc != -EREMOTE) 3465 + goto out; 3451 3466 3452 3467 if (rc != -EREMOTE) { 3453 3468 rc = cifs_are_all_path_components_accessible(server, xid, tcon, ··· 3465 3468 } 3466 3469 } 3467 3470 3471 + out: 3468 3472 kfree(full_path); 3469 3473 return rc; 3470 3474 } ··· 3701 3703 if (!isdfs) 3702 3704 goto out; 3703 3705 3706 + /* proceed as DFS mount */ 3704 3707 uuid_gen(&mnt_ctx.mount_id); 3705 3708 rc = connect_dfs_root(&mnt_ctx, &tl); 3706 3709 dfs_cache_free_tgts(&tl); ··· 3959 3960 if (rc == 0) { 3960 3961 spin_lock(&cifs_tcp_ses_lock); 3961 3962 if (server->tcpStatus == CifsInNegotiate) 3962 - server->tcpStatus = CifsNeedSessSetup; 3963 + server->tcpStatus = CifsGood; 3963 3964 else 3964 3965 rc = -EHOSTDOWN; 3965 3966 spin_unlock(&cifs_tcp_ses_lock); ··· 3981 3982 int rc = -ENOSYS; 3982 3983 bool is_binding = false; 3983 3984 3984 - /* only send once per connect */ 3985 + 3985 3986 spin_lock(&cifs_tcp_ses_lock); 3986 - if ((server->tcpStatus != CifsNeedSessSetup) && 3987 - (ses->status == CifsGood)) { 3987 + if (ses->ses_status != SES_GOOD && 3988 + ses->ses_status != SES_NEW && 3989 + ses->ses_status != SES_NEED_RECON) { 3988 3990 spin_unlock(&cifs_tcp_ses_lock); 3989 3991 return 0; 3990 3992 } 3991 - server->tcpStatus = CifsInSessSetup; 3992 - spin_unlock(&cifs_tcp_ses_lock); 3993 3993 3994 + /* only send once per connect */ 3994 3995 spin_lock(&ses->chan_lock); 3996 + if (CIFS_ALL_CHANS_GOOD(ses) || 3997 + cifs_chan_in_reconnect(ses, server)) { 3998 + spin_unlock(&ses->chan_lock); 3999 + spin_unlock(&cifs_tcp_ses_lock); 4000 + return 0; 4001 + } 3995 4002 is_binding = !CIFS_ALL_CHANS_NEED_RECONNECT(ses); 4003 + cifs_chan_set_in_reconnect(ses, server); 3996 4004 spin_unlock(&ses->chan_lock); 4005 + 4006 + if (!is_binding) 4007 + ses->ses_status = SES_IN_SETUP; 4008 + spin_unlock(&cifs_tcp_ses_lock); 3997 4009 3998 4010 if (!is_binding) { 3999 4011 ses->capabilities = server->capabilities; ··· 4029 4019 if (rc) { 4030 4020 cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc); 4031 4021 spin_lock(&cifs_tcp_ses_lock); 4032 - if (server->tcpStatus == CifsInSessSetup) 4033 - server->tcpStatus = CifsNeedSessSetup; 4022 + if (ses->ses_status == SES_IN_SETUP) 4023 + ses->ses_status = SES_NEED_RECON; 4024 + spin_lock(&ses->chan_lock); 4025 + cifs_chan_clear_in_reconnect(ses, server); 4026 + spin_unlock(&ses->chan_lock); 4034 4027 spin_unlock(&cifs_tcp_ses_lock); 4035 4028 } else { 4036 4029 spin_lock(&cifs_tcp_ses_lock); 4037 - if (server->tcpStatus == CifsInSessSetup) 4038 - server->tcpStatus = CifsGood; 4039 - /* Even if one channel is active, session is in good state */ 4040 - ses->status = CifsGood; 4041 - spin_unlock(&cifs_tcp_ses_lock); 4042 - 4030 + if (ses->ses_status == SES_IN_SETUP) 4031 + ses->ses_status = SES_GOOD; 4043 4032 spin_lock(&ses->chan_lock); 4033 + cifs_chan_clear_in_reconnect(ses, server); 4044 4034 cifs_chan_clear_need_reconnect(ses, server); 4045 4035 spin_unlock(&ses->chan_lock); 4036 + spin_unlock(&cifs_tcp_ses_lock); 4046 4037 } 4047 4038 4048 4039 return rc; ··· 4508 4497 4509 4498 /* only send once per connect */ 4510 4499 spin_lock(&cifs_tcp_ses_lock); 4511 - if (tcon->ses->status != CifsGood || 4500 + if (tcon->ses->ses_status != SES_GOOD || 4512 4501 (tcon->status != TID_NEW && 4513 4502 tcon->status != TID_NEED_TCON)) { 4514 4503 spin_unlock(&cifs_tcp_ses_lock); ··· 4576 4565 4577 4566 /* only send once per connect */ 4578 4567 spin_lock(&cifs_tcp_ses_lock); 4579 - if (tcon->ses->status != CifsGood || 4568 + if (tcon->ses->ses_status != SES_GOOD || 4580 4569 (tcon->status != TID_NEW && 4581 4570 tcon->status != TID_NEED_TCON)) { 4582 4571 spin_unlock(&cifs_tcp_ses_lock);
+3 -3
fs/cifs/dfs_cache.c
··· 654 654 return ce; 655 655 } 656 656 } 657 - return ERR_PTR(-EEXIST); 657 + return ERR_PTR(-ENOENT); 658 658 } 659 659 660 660 /* ··· 662 662 * 663 663 * Use whole path components in the match. Must be called with htable_rw_lock held. 664 664 * 665 - * Return ERR_PTR(-EEXIST) if the entry is not found. 665 + * Return ERR_PTR(-ENOENT) if the entry is not found. 666 666 */ 667 667 static struct cache_entry *lookup_cache_entry(const char *path) 668 668 { ··· 710 710 while (e > s && *e != sep) 711 711 e--; 712 712 } 713 - return ERR_PTR(-EEXIST); 713 + return ERR_PTR(-ENOENT); 714 714 } 715 715 716 716 /**
+8 -5
fs/cifs/file.c
··· 1395 1395 cifs_dbg(VFS, "Can't push all brlocks!\n"); 1396 1396 break; 1397 1397 } 1398 - length = 1 + flock->fl_end - flock->fl_start; 1398 + length = cifs_flock_len(flock); 1399 1399 if (flock->fl_type == F_RDLCK || flock->fl_type == F_SHLCK) 1400 1400 type = CIFS_RDLCK; 1401 1401 else ··· 1511 1511 bool wait_flag, bool posix_lck, unsigned int xid) 1512 1512 { 1513 1513 int rc = 0; 1514 - __u64 length = 1 + flock->fl_end - flock->fl_start; 1514 + __u64 length = cifs_flock_len(flock); 1515 1515 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 1516 1516 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1517 1517 struct TCP_Server_Info *server = tcon->ses->server; ··· 1609 1609 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1610 1610 struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry)); 1611 1611 struct cifsLockInfo *li, *tmp; 1612 - __u64 length = 1 + flock->fl_end - flock->fl_start; 1612 + __u64 length = cifs_flock_len(flock); 1613 1613 struct list_head tmp_llist; 1614 1614 1615 1615 INIT_LIST_HEAD(&tmp_llist); ··· 1713 1713 unsigned int xid) 1714 1714 { 1715 1715 int rc = 0; 1716 - __u64 length = 1 + flock->fl_end - flock->fl_start; 1716 + __u64 length = cifs_flock_len(flock); 1717 1717 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 1718 1718 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1719 1719 struct TCP_Server_Info *server = tcon->ses->server; ··· 2777 2777 rc = filemap_write_and_wait(inode->i_mapping); 2778 2778 2779 2779 cifs_dbg(FYI, "Flush inode %p file %p rc %d\n", inode, file, rc); 2780 - if (rc) 2780 + if (rc) { 2781 + /* get more nuanced writeback errors */ 2782 + rc = filemap_check_wb_err(file->f_mapping, 0); 2781 2783 trace_cifs_flush_err(inode->i_ino, rc); 2784 + } 2782 2785 return rc; 2783 2786 } 2784 2787
+8 -25
fs/cifs/fs_context.c
··· 119 119 fsparam_flag_no("persistenthandles", Opt_persistent), 120 120 fsparam_flag_no("resilienthandles", Opt_resilient), 121 121 fsparam_flag_no("tcpnodelay", Opt_tcp_nodelay), 122 + fsparam_flag("nosparse", Opt_nosparse), 122 123 fsparam_flag("domainauto", Opt_domainauto), 123 124 fsparam_flag("rdma", Opt_rdma), 124 125 fsparam_flag("modesid", Opt_modesid), ··· 313 312 new_ctx->password = NULL; 314 313 new_ctx->server_hostname = NULL; 315 314 new_ctx->domainname = NULL; 316 - new_ctx->workstation_name = NULL; 317 315 new_ctx->UNC = NULL; 318 316 new_ctx->source = NULL; 319 317 new_ctx->iocharset = NULL; ··· 327 327 DUP_CTX_STR(UNC); 328 328 DUP_CTX_STR(source); 329 329 DUP_CTX_STR(domainname); 330 - DUP_CTX_STR(workstation_name); 331 330 DUP_CTX_STR(nodename); 332 331 DUP_CTX_STR(iocharset); 333 332 ··· 765 766 cifs_errorf(fc, "can not change domainname during remount\n"); 766 767 return -EINVAL; 767 768 } 768 - if (new_ctx->workstation_name && 769 - (!old_ctx->workstation_name || strcmp(new_ctx->workstation_name, old_ctx->workstation_name))) { 769 + if (strcmp(new_ctx->workstation_name, old_ctx->workstation_name)) { 770 770 cifs_errorf(fc, "can not change workstation_name during remount\n"); 771 771 return -EINVAL; 772 772 } ··· 812 814 STEAL_STRING(cifs_sb, ctx, username); 813 815 STEAL_STRING(cifs_sb, ctx, password); 814 816 STEAL_STRING(cifs_sb, ctx, domainname); 815 - STEAL_STRING(cifs_sb, ctx, workstation_name); 816 817 STEAL_STRING(cifs_sb, ctx, nodename); 817 818 STEAL_STRING(cifs_sb, ctx, iocharset); 818 819 ··· 939 942 break; 940 943 case Opt_nolease: 941 944 ctx->no_lease = 1; 945 + break; 946 + case Opt_nosparse: 947 + ctx->no_sparse = 1; 942 948 break; 943 949 case Opt_nodelete: 944 950 ctx->nodelete = 1; ··· 1467 1467 1468 1468 int smb3_init_fs_context(struct fs_context *fc) 1469 1469 { 1470 - int rc; 1471 1470 struct smb3_fs_context *ctx; 1472 1471 char *nodename = utsname()->nodename; 1473 1472 int i; 1474 1473 1475 1474 ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL); 1476 - if (unlikely(!ctx)) { 1477 - rc = -ENOMEM; 1478 - goto err_exit; 1479 - } 1475 + if (unlikely(!ctx)) 1476 + return -ENOMEM; 1480 1477 1481 - ctx->workstation_name = kstrdup(nodename, GFP_KERNEL); 1482 - if (unlikely(!ctx->workstation_name)) { 1483 - rc = -ENOMEM; 1484 - goto err_exit; 1485 - } 1478 + strscpy(ctx->workstation_name, nodename, sizeof(ctx->workstation_name)); 1486 1479 1487 1480 /* 1488 1481 * does not have to be perfect mapping since field is ··· 1548 1555 fc->fs_private = ctx; 1549 1556 fc->ops = &smb3_fs_context_ops; 1550 1557 return 0; 1551 - 1552 - err_exit: 1553 - if (ctx) { 1554 - kfree(ctx->workstation_name); 1555 - kfree(ctx); 1556 - } 1557 - 1558 - return rc; 1559 1558 } 1560 1559 1561 1560 void ··· 1573 1588 ctx->source = NULL; 1574 1589 kfree(ctx->domainname); 1575 1590 ctx->domainname = NULL; 1576 - kfree(ctx->workstation_name); 1577 - ctx->workstation_name = NULL; 1578 1591 kfree(ctx->nodename); 1579 1592 ctx->nodename = NULL; 1580 1593 kfree(ctx->iocharset);
+3 -1
fs/cifs/fs_context.h
··· 62 62 Opt_noblocksend, 63 63 Opt_noautotune, 64 64 Opt_nolease, 65 + Opt_nosparse, 65 66 Opt_hard, 66 67 Opt_soft, 67 68 Opt_perm, ··· 171 170 char *server_hostname; 172 171 char *UNC; 173 172 char *nodename; 174 - char *workstation_name; 173 + char workstation_name[CIFS_MAX_WORKSTATION_LEN]; 175 174 char *iocharset; /* local code page for mapping to and from Unicode */ 176 175 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */ 177 176 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */ ··· 223 222 bool noautotune:1; 224 223 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ 225 224 bool no_lease:1; /* disable requesting leases */ 225 + bool no_sparse:1; /* do not attempt to set files sparse */ 226 226 bool fsc:1; /* enable fscache */ 227 227 bool mfsymlinks:1; /* use Minshall+French Symlinks */ 228 228 bool multiuser:1;
+4 -7
fs/cifs/misc.c
··· 69 69 ret_buf = kzalloc(sizeof(struct cifs_ses), GFP_KERNEL); 70 70 if (ret_buf) { 71 71 atomic_inc(&sesInfoAllocCount); 72 - ret_buf->status = CifsNew; 72 + ret_buf->ses_status = SES_NEW; 73 73 ++ret_buf->ses_count; 74 74 INIT_LIST_HEAD(&ret_buf->smb_ses_list); 75 75 INIT_LIST_HEAD(&ret_buf->tcon_list); ··· 95 95 kfree_sensitive(buf_to_free->password); 96 96 kfree(buf_to_free->user_name); 97 97 kfree(buf_to_free->domainName); 98 - kfree(buf_to_free->workstation_name); 99 98 kfree_sensitive(buf_to_free->auth_key.response); 100 99 kfree(buf_to_free->iface_list); 101 100 kfree_sensitive(buf_to_free); ··· 113 114 kfree(ret_buf); 114 115 return NULL; 115 116 } 117 + INIT_LIST_HEAD(&ret_buf->crfid.dirents.entries); 118 + mutex_init(&ret_buf->crfid.dirents.de_mutex); 116 119 117 120 atomic_inc(&tconInfoAllocCount); 118 121 ret_buf->status = TID_NEW; ··· 1310 1309 * for "\<server>\<dfsname>\<linkpath>" DFS reference, 1311 1310 * where <dfsname> contains non-ASCII unicode symbols. 1312 1311 * 1313 - * Check such DFS reference and emulate -ENOENT if it is actual. 1312 + * Check such DFS reference. 1314 1313 */ 1315 1314 int cifs_dfs_query_info_nonascii_quirk(const unsigned int xid, 1316 1315 struct cifs_tcon *tcon, ··· 1342 1341 cifs_dbg(FYI, "DFS ref '%s' is found, emulate -EREMOTE\n", 1343 1342 dfspath); 1344 1343 rc = -EREMOTE; 1345 - } else if (rc == -EEXIST) { 1346 - cifs_dbg(FYI, "DFS ref '%s' is not found, emulate -ENOENT\n", 1347 - dfspath); 1348 - rc = -ENOENT; 1349 1344 } else { 1350 1345 cifs_dbg(FYI, "%s: dfs_cache_find returned %d\n", __func__, rc); 1351 1346 }
+171 -8
fs/cifs/readdir.c
··· 840 840 return rc; 841 841 } 842 842 843 + static bool emit_cached_dirents(struct cached_dirents *cde, 844 + struct dir_context *ctx) 845 + { 846 + struct cached_dirent *dirent; 847 + int rc; 848 + 849 + list_for_each_entry(dirent, &cde->entries, entry) { 850 + if (ctx->pos >= dirent->pos) 851 + continue; 852 + ctx->pos = dirent->pos; 853 + rc = dir_emit(ctx, dirent->name, dirent->namelen, 854 + dirent->fattr.cf_uniqueid, 855 + dirent->fattr.cf_dtype); 856 + if (!rc) 857 + return rc; 858 + } 859 + return true; 860 + } 861 + 862 + static void update_cached_dirents_count(struct cached_dirents *cde, 863 + struct dir_context *ctx) 864 + { 865 + if (cde->ctx != ctx) 866 + return; 867 + if (cde->is_valid || cde->is_failed) 868 + return; 869 + 870 + cde->pos++; 871 + } 872 + 873 + static void finished_cached_dirents_count(struct cached_dirents *cde, 874 + struct dir_context *ctx) 875 + { 876 + if (cde->ctx != ctx) 877 + return; 878 + if (cde->is_valid || cde->is_failed) 879 + return; 880 + if (ctx->pos != cde->pos) 881 + return; 882 + 883 + cde->is_valid = 1; 884 + } 885 + 886 + static void add_cached_dirent(struct cached_dirents *cde, 887 + struct dir_context *ctx, 888 + const char *name, int namelen, 889 + struct cifs_fattr *fattr) 890 + { 891 + struct cached_dirent *de; 892 + 893 + if (cde->ctx != ctx) 894 + return; 895 + if (cde->is_valid || cde->is_failed) 896 + return; 897 + if (ctx->pos != cde->pos) { 898 + cde->is_failed = 1; 899 + return; 900 + } 901 + de = kzalloc(sizeof(*de), GFP_ATOMIC); 902 + if (de == NULL) { 903 + cde->is_failed = 1; 904 + return; 905 + } 906 + de->namelen = namelen; 907 + de->name = kstrndup(name, namelen, GFP_ATOMIC); 908 + if (de->name == NULL) { 909 + kfree(de); 910 + cde->is_failed = 1; 911 + return; 912 + } 913 + de->pos = ctx->pos; 914 + 915 + memcpy(&de->fattr, fattr, sizeof(struct cifs_fattr)); 916 + 917 + list_add_tail(&de->entry, &cde->entries); 918 + } 919 + 920 + static bool cifs_dir_emit(struct dir_context *ctx, 921 + const char *name, int namelen, 922 + struct cifs_fattr *fattr, 923 + struct cached_fid *cfid) 924 + { 925 + bool rc; 926 + ino_t ino = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); 927 + 928 + rc = dir_emit(ctx, name, namelen, ino, fattr->cf_dtype); 929 + if (!rc) 930 + return rc; 931 + 932 + if (cfid) { 933 + mutex_lock(&cfid->dirents.de_mutex); 934 + add_cached_dirent(&cfid->dirents, ctx, name, namelen, 935 + fattr); 936 + mutex_unlock(&cfid->dirents.de_mutex); 937 + } 938 + 939 + return rc; 940 + } 941 + 843 942 static int cifs_filldir(char *find_entry, struct file *file, 844 - struct dir_context *ctx, 845 - char *scratch_buf, unsigned int max_len) 943 + struct dir_context *ctx, 944 + char *scratch_buf, unsigned int max_len, 945 + struct cached_fid *cfid) 846 946 { 847 947 struct cifsFileInfo *file_info = file->private_data; 848 948 struct super_block *sb = file_inode(file)->i_sb; ··· 951 851 struct cifs_fattr fattr; 952 852 struct qstr name; 953 853 int rc = 0; 954 - ino_t ino; 955 854 956 855 rc = cifs_fill_dirent(&de, find_entry, file_info->srch_inf.info_level, 957 856 file_info->srch_inf.unicode); ··· 1030 931 1031 932 cifs_prime_dcache(file_dentry(file), &name, &fattr); 1032 933 1033 - ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); 1034 - return !dir_emit(ctx, name.name, name.len, ino, fattr.cf_dtype); 934 + return !cifs_dir_emit(ctx, name.name, name.len, 935 + &fattr, cfid); 1035 936 } 1036 937 1037 938 ··· 1040 941 int rc = 0; 1041 942 unsigned int xid; 1042 943 int i; 944 + struct tcon_link *tlink = NULL; 1043 945 struct cifs_tcon *tcon; 1044 - struct cifsFileInfo *cifsFile = NULL; 946 + struct cifsFileInfo *cifsFile; 1045 947 char *current_entry; 1046 948 int num_to_fill = 0; 1047 949 char *tmp_buf = NULL; ··· 1050 950 unsigned int max_len; 1051 951 const char *full_path; 1052 952 void *page = alloc_dentry_path(); 953 + struct cached_fid *cfid = NULL; 954 + struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); 1053 955 1054 956 xid = get_xid(); 1055 957 ··· 1061 959 goto rddir2_exit; 1062 960 } 1063 961 962 + if (file->private_data == NULL) { 963 + tlink = cifs_sb_tlink(cifs_sb); 964 + if (IS_ERR(tlink)) 965 + goto cache_not_found; 966 + tcon = tlink_tcon(tlink); 967 + } else { 968 + cifsFile = file->private_data; 969 + tcon = tlink_tcon(cifsFile->tlink); 970 + } 971 + 972 + rc = open_cached_dir(xid, tcon, full_path, cifs_sb, &cfid); 973 + cifs_put_tlink(tlink); 974 + if (rc) 975 + goto cache_not_found; 976 + 977 + mutex_lock(&cfid->dirents.de_mutex); 978 + /* 979 + * If this was reading from the start of the directory 980 + * we need to initialize scanning and storing the 981 + * directory content. 982 + */ 983 + if (ctx->pos == 0 && cfid->dirents.ctx == NULL) { 984 + cfid->dirents.ctx = ctx; 985 + cfid->dirents.pos = 2; 986 + } 987 + /* 988 + * If we already have the entire directory cached then 989 + * we can just serve the cache. 990 + */ 991 + if (cfid->dirents.is_valid) { 992 + if (!dir_emit_dots(file, ctx)) { 993 + mutex_unlock(&cfid->dirents.de_mutex); 994 + goto rddir2_exit; 995 + } 996 + emit_cached_dirents(&cfid->dirents, ctx); 997 + mutex_unlock(&cfid->dirents.de_mutex); 998 + goto rddir2_exit; 999 + } 1000 + mutex_unlock(&cfid->dirents.de_mutex); 1001 + 1002 + /* Drop the cache while calling initiate_cifs_search and 1003 + * find_cifs_entry in case there will be reconnects during 1004 + * query_directory. 1005 + */ 1006 + close_cached_dir(cfid); 1007 + cfid = NULL; 1008 + 1009 + cache_not_found: 1064 1010 /* 1065 1011 * Ensure FindFirst doesn't fail before doing filldir() for '.' and 1066 1012 * '..'. Otherwise we won't be able to notify VFS in case of failure. ··· 1127 977 is in current search buffer? 1128 978 if it before then restart search 1129 979 if after then keep searching till find it */ 1130 - 1131 980 cifsFile = file->private_data; 1132 981 if (cifsFile->srch_inf.endOfSearch) { 1133 982 if (cifsFile->srch_inf.emptyDir) { ··· 1142 993 tcon = tlink_tcon(cifsFile->tlink); 1143 994 rc = find_cifs_entry(xid, tcon, ctx->pos, file, full_path, 1144 995 &current_entry, &num_to_fill); 996 + open_cached_dir(xid, tcon, full_path, cifs_sb, &cfid); 1145 997 if (rc) { 1146 998 cifs_dbg(FYI, "fce error %d\n", rc); 1147 999 goto rddir2_exit; 1148 1000 } else if (current_entry != NULL) { 1149 1001 cifs_dbg(FYI, "entry %lld found\n", ctx->pos); 1150 1002 } else { 1003 + if (cfid) { 1004 + mutex_lock(&cfid->dirents.de_mutex); 1005 + finished_cached_dirents_count(&cfid->dirents, ctx); 1006 + mutex_unlock(&cfid->dirents.de_mutex); 1007 + } 1151 1008 cifs_dbg(FYI, "Could not find entry\n"); 1152 1009 goto rddir2_exit; 1153 1010 } ··· 1183 1028 */ 1184 1029 *tmp_buf = 0; 1185 1030 rc = cifs_filldir(current_entry, file, ctx, 1186 - tmp_buf, max_len); 1031 + tmp_buf, max_len, cfid); 1187 1032 if (rc) { 1188 1033 if (rc > 0) 1189 1034 rc = 0; ··· 1191 1036 } 1192 1037 1193 1038 ctx->pos++; 1039 + if (cfid) { 1040 + mutex_lock(&cfid->dirents.de_mutex); 1041 + update_cached_dirents_count(&cfid->dirents, ctx); 1042 + mutex_unlock(&cfid->dirents.de_mutex); 1043 + } 1044 + 1194 1045 if (ctx->pos == 1195 1046 cifsFile->srch_inf.index_of_last_entry) { 1196 1047 cifs_dbg(FYI, "last entry in buf at pos %lld %s\n", ··· 1211 1050 kfree(tmp_buf); 1212 1051 1213 1052 rddir2_exit: 1053 + if (cfid) 1054 + close_cached_dir(cfid); 1214 1055 free_dentry_path(page); 1215 1056 free_xid(xid); 1216 1057 return rc;
+30 -3
fs/cifs/sess.c
··· 86 86 } 87 87 88 88 void 89 + cifs_chan_set_in_reconnect(struct cifs_ses *ses, 90 + struct TCP_Server_Info *server) 91 + { 92 + unsigned int chan_index = cifs_ses_get_chan_index(ses, server); 93 + 94 + ses->chans[chan_index].in_reconnect = true; 95 + } 96 + 97 + void 98 + cifs_chan_clear_in_reconnect(struct cifs_ses *ses, 99 + struct TCP_Server_Info *server) 100 + { 101 + unsigned int chan_index = cifs_ses_get_chan_index(ses, server); 102 + 103 + ses->chans[chan_index].in_reconnect = false; 104 + } 105 + 106 + bool 107 + cifs_chan_in_reconnect(struct cifs_ses *ses, 108 + struct TCP_Server_Info *server) 109 + { 110 + unsigned int chan_index = cifs_ses_get_chan_index(ses, server); 111 + 112 + return CIFS_CHAN_IN_RECONNECT(ses, chan_index); 113 + } 114 + 115 + void 89 116 cifs_chan_set_need_reconnect(struct cifs_ses *ses, 90 117 struct TCP_Server_Info *server) 91 118 { ··· 741 714 else 742 715 sz += sizeof(__le16); 743 716 744 - if (ses->workstation_name) 717 + if (ses->workstation_name[0]) 745 718 sz += sizeof(__le16) * strnlen(ses->workstation_name, 746 - CIFS_MAX_WORKSTATION_LEN); 719 + ntlmssp_workstation_name_size(ses)); 747 720 else 748 721 sz += sizeof(__le16); 749 722 ··· 987 960 988 961 cifs_security_buffer_from_str(&sec_blob->WorkstationName, 989 962 ses->workstation_name, 990 - CIFS_MAX_WORKSTATION_LEN, 963 + ntlmssp_workstation_name_size(ses), 991 964 *pbuffer, &tmp, 992 965 nls_cp); 993 966
+4 -3
fs/cifs/smb2inode.c
··· 362 362 num_rqst++; 363 363 364 364 if (cfile) { 365 - cifsFileInfo_put(cfile); 366 - cfile = NULL; 367 365 rc = compound_send_recv(xid, ses, server, 368 366 flags, num_rqst - 2, 369 367 &rqst[1], &resp_buftype[1], ··· 512 514 if (smb2_data == NULL) 513 515 return -ENOMEM; 514 516 517 + if (strcmp(full_path, "")) 518 + rc = -ENOENT; 519 + else 520 + rc = open_cached_dir(xid, tcon, full_path, cifs_sb, &cfid); 515 521 /* If it is a root and its handle is cached then use it */ 516 - rc = open_cached_dir(xid, tcon, full_path, cifs_sb, &cfid); 517 522 if (!rc) { 518 523 if (tcon->crfid.file_all_info_is_valid) { 519 524 move_smb2_info_to_cifs(data,
+11 -1
fs/cifs/smb2misc.c
··· 656 656 } 657 657 spin_unlock(&cifs_tcp_ses_lock); 658 658 cifs_dbg(FYI, "Can not process lease break - no lease matched\n"); 659 + trace_smb3_lease_not_found(le32_to_cpu(rsp->CurrentLeaseState), 660 + le32_to_cpu(rsp->hdr.Id.SyncId.TreeId), 661 + le64_to_cpu(rsp->hdr.SessionId), 662 + *((u64 *)rsp->LeaseKey), 663 + *((u64 *)&rsp->LeaseKey[8])); 664 + 659 665 return false; 660 666 } 661 667 ··· 732 726 } 733 727 spin_unlock(&cifs_tcp_ses_lock); 734 728 cifs_dbg(FYI, "No file id matched, oplock break ignored\n"); 729 + trace_smb3_oplock_not_found(0 /* no xid */, rsp->PersistentFid, 730 + le32_to_cpu(rsp->hdr.Id.SyncId.TreeId), 731 + le64_to_cpu(rsp->hdr.SessionId)); 732 + 735 733 return true; 736 734 } 737 735 ··· 808 798 if (tcon->ses) 809 799 server = tcon->ses->server; 810 800 811 - cifs_server_dbg(FYI, "tid=%u: tcon is closing, skipping async close retry of fid %llu %llu\n", 801 + cifs_server_dbg(FYI, "tid=0x%x: tcon is closing, skipping async close retry of fid %llu %llu\n", 812 802 tcon->tid, persistent_fid, volatile_fid); 813 803 814 804 return 0;
+27 -5
fs/cifs/smb2ops.c
··· 699 699 { 700 700 struct cached_fid *cfid = container_of(ref, struct cached_fid, 701 701 refcount); 702 + struct cached_dirent *dirent, *q; 702 703 703 704 if (cfid->is_valid) { 704 705 cifs_dbg(FYI, "clear cached root file handle\n"); ··· 719 718 dput(cfid->dentry); 720 719 cfid->dentry = NULL; 721 720 } 721 + /* 722 + * Delete all cached dirent names 723 + */ 724 + mutex_lock(&cfid->dirents.de_mutex); 725 + list_for_each_entry_safe(dirent, q, &cfid->dirents.entries, entry) { 726 + list_del(&dirent->entry); 727 + kfree(dirent->name); 728 + kfree(dirent); 729 + } 730 + cfid->dirents.is_valid = 0; 731 + cfid->dirents.is_failed = 0; 732 + cfid->dirents.ctx = NULL; 733 + cfid->dirents.pos = 0; 734 + mutex_unlock(&cfid->dirents.de_mutex); 735 + 722 736 } 723 737 724 738 void close_cached_dir(struct cached_fid *cfid) ··· 770 754 /* 771 755 * Open the and cache a directory handle. 772 756 * Only supported for the root handle. 757 + * If error then *cfid is not initialized. 773 758 */ 774 759 int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon, 775 760 const char *path, 776 761 struct cifs_sb_info *cifs_sb, 777 762 struct cached_fid **cfid) 778 763 { 779 - struct cifs_ses *ses = tcon->ses; 780 - struct TCP_Server_Info *server = ses->server; 764 + struct cifs_ses *ses; 765 + struct TCP_Server_Info *server; 781 766 struct cifs_open_parms oparms; 782 767 struct smb2_create_rsp *o_rsp = NULL; 783 768 struct smb2_query_info_rsp *qi_rsp = NULL; ··· 793 776 struct cifs_fid *pfid; 794 777 struct dentry *dentry; 795 778 796 - if (tcon->nohandlecache) 779 + if (tcon == NULL || tcon->nohandlecache || 780 + is_smb1_server(tcon->ses->server)) 797 781 return -ENOTSUPP; 782 + 783 + ses = tcon->ses; 784 + server = ses->server; 798 785 799 786 if (cifs_sb->root == NULL) 800 787 return -ENOENT; ··· 845 824 rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE; 846 825 847 826 oparms.tcon = tcon; 848 - oparms.create_options = cifs_create_options(cifs_sb, 0); 827 + oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE); 849 828 oparms.desired_access = FILE_READ_ATTRIBUTES; 850 829 oparms.disposition = FILE_OPEN; 851 830 oparms.fid = pfid; ··· 2716 2695 resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; 2717 2696 memset(rsp_iov, 0, sizeof(rsp_iov)); 2718 2697 2719 - rc = open_cached_dir(xid, tcon, path, cifs_sb, &cfid); 2698 + if (!strcmp(path, "")) 2699 + open_cached_dir(xid, tcon, path, cifs_sb, &cfid); /* cfid null if open dir failed */ 2720 2700 2721 2701 memset(&open_iov, 0, sizeof(open_iov)); 2722 2702 rqst[0].rq_iov = open_iov;
+3 -2
fs/cifs/smb2pdu.c
··· 179 179 } 180 180 } 181 181 spin_unlock(&cifs_tcp_ses_lock); 182 - if ((!tcon->ses) || (tcon->ses->status == CifsExiting) || 182 + if ((!tcon->ses) || (tcon->ses->ses_status == SES_EXITING) || 183 183 (!tcon->ses->server) || !server) 184 184 return -EIO; 185 185 ··· 3899 3899 cifs_dbg(FYI, "In echo request for conn_id %lld\n", server->conn_id); 3900 3900 3901 3901 spin_lock(&cifs_tcp_ses_lock); 3902 - if (server->tcpStatus == CifsNeedNegotiate) { 3902 + if (server->ops->need_neg && 3903 + server->ops->need_neg(server)) { 3903 3904 spin_unlock(&cifs_tcp_ses_lock); 3904 3905 /* No need to send echo on newly established connections */ 3905 3906 mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
-22
fs/cifs/smb2pdu.h
··· 260 260 struct smb3_extents extents[]; 261 261 } __packed; 262 262 263 - struct fsctl_set_integrity_information_req { 264 - __le16 ChecksumAlgorithm; 265 - __le16 Reserved; 266 - __le32 Flags; 267 - } __packed; 268 - 269 - struct fsctl_get_integrity_information_rsp { 270 - __le16 ChecksumAlgorithm; 271 - __le16 Reserved; 272 - __le32 Flags; 273 - __le32 ChecksumChunkSizeInBytes; 274 - __le32 ClusterSizeInBytes; 275 - } __packed; 276 - 277 - /* Integrity ChecksumAlgorithm choices for above */ 278 - #define CHECKSUM_TYPE_NONE 0x0000 279 - #define CHECKSUM_TYPE_CRC64 0x0002 280 - #define CHECKSUM_TYPE_UNCHANGED 0xFFFF /* set only */ 281 - 282 - /* Integrity flags for above */ 283 - #define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001 284 - 285 263 /* See MS-DFSC 2.2.2 */ 286 264 struct fsctl_get_dfs_referral_req { 287 265 __le16 MaxReferralLevel;
+4 -3
fs/cifs/smb2transport.c
··· 641 641 if (!is_signed) 642 642 return 0; 643 643 spin_lock(&cifs_tcp_ses_lock); 644 - if (server->tcpStatus == CifsNeedNegotiate) { 644 + if (server->ops->need_neg && 645 + server->ops->need_neg(server)) { 645 646 spin_unlock(&cifs_tcp_ses_lock); 646 647 return 0; 647 648 } ··· 780 779 return -EAGAIN; 781 780 } 782 781 783 - if (ses->status == CifsNew) { 782 + if (ses->ses_status == SES_NEW) { 784 783 if ((shdr->Command != SMB2_SESSION_SETUP) && 785 784 (shdr->Command != SMB2_NEGOTIATE)) { 786 785 spin_unlock(&cifs_tcp_ses_lock); ··· 789 788 /* else ok - we are setting up session */ 790 789 } 791 790 792 - if (ses->status == CifsExiting) { 791 + if (ses->ses_status == SES_EXITING) { 793 792 if (shdr->Command != SMB2_LOGOFF) { 794 793 spin_unlock(&cifs_tcp_ses_lock); 795 794 return -EAGAIN;
+1 -1
fs/cifs/smbdirect.c
··· 1350 1350 wait_event(info->wait_send_pending, 1351 1351 atomic_read(&info->send_pending) == 0); 1352 1352 1353 - /* It's not posssible for upper layer to get to reassembly */ 1353 + /* It's not possible for upper layer to get to reassembly */ 1354 1354 log_rdma_event(INFO, "drain the reassembly queue\n"); 1355 1355 do { 1356 1356 spin_lock_irqsave(&info->reassembly_queue_lock, flags);
+2
fs/cifs/trace.h
··· 158 158 DEFINE_SMB3_FD_EVENT(flush_done); 159 159 DEFINE_SMB3_FD_EVENT(close_enter); 160 160 DEFINE_SMB3_FD_EVENT(close_done); 161 + DEFINE_SMB3_FD_EVENT(oplock_not_found); 161 162 162 163 DECLARE_EVENT_CLASS(smb3_fd_err_class, 163 164 TP_PROTO(unsigned int xid, ··· 815 814 TP_ARGS(lease_state, tid, sesid, lease_key_low, lease_key_high)) 816 815 817 816 DEFINE_SMB3_LEASE_DONE_EVENT(lease_done); 817 + DEFINE_SMB3_LEASE_DONE_EVENT(lease_not_found); 818 818 819 819 DECLARE_EVENT_CLASS(smb3_lease_err_class, 820 820 TP_PROTO(__u32 lease_state,
+4 -4
fs/cifs/transport.c
··· 726 726 struct mid_q_entry **ppmidQ) 727 727 { 728 728 spin_lock(&cifs_tcp_ses_lock); 729 - if (ses->status == CifsNew) { 729 + if (ses->ses_status == SES_NEW) { 730 730 if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && 731 731 (in_buf->Command != SMB_COM_NEGOTIATE)) { 732 732 spin_unlock(&cifs_tcp_ses_lock); ··· 735 735 /* else ok - we are setting up session */ 736 736 } 737 737 738 - if (ses->status == CifsExiting) { 738 + if (ses->ses_status == SES_EXITING) { 739 739 /* check if SMB session is bad because we are setting it up */ 740 740 if (in_buf->Command != SMB_COM_LOGOFF_ANDX) { 741 741 spin_unlock(&cifs_tcp_ses_lock); ··· 1187 1187 * Compounding is never used during session establish. 1188 1188 */ 1189 1189 spin_lock(&cifs_tcp_ses_lock); 1190 - if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) { 1190 + if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) { 1191 1191 spin_unlock(&cifs_tcp_ses_lock); 1192 1192 1193 1193 mutex_lock(&server->srv_mutex); ··· 1260 1260 * Compounding is never used during session establish. 1261 1261 */ 1262 1262 spin_lock(&cifs_tcp_ses_lock); 1263 - if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) { 1263 + if ((ses->ses_status == SES_NEW) || (optype & CIFS_NEG_OP) || (optype & CIFS_SESS_OP)) { 1264 1264 struct kvec iov = { 1265 1265 .iov_base = resp_iov[0].iov_base, 1266 1266 .iov_len = resp_iov[0].iov_len
+101 -7
fs/smbfs_common/smb2pdu.h
··· 1244 1244 __le64 BeyondFinalZero; 1245 1245 } __packed; 1246 1246 1247 + /* See MS-FSCC 2.3.7 */ 1248 + struct duplicate_extents_to_file { 1249 + __u64 PersistentFileHandle; /* source file handle, opaque endianness */ 1250 + __u64 VolatileFileHandle; 1251 + __le64 SourceFileOffset; 1252 + __le64 TargetFileOffset; 1253 + __le64 ByteCount; /* Bytes to be copied */ 1254 + } __packed; 1255 + 1256 + /* See MS-FSCC 2.3.8 */ 1257 + #define DUPLICATE_EXTENTS_DATA_EX_SOURCE_ATOMIC 0x00000001 1258 + struct duplicate_extents_to_file_ex { 1259 + __u64 PersistentFileHandle; /* source file handle, opaque endianness */ 1260 + __u64 VolatileFileHandle; 1261 + __le64 SourceFileOffset; 1262 + __le64 TargetFileOffset; 1263 + __le64 ByteCount; /* Bytes to be copied */ 1264 + __le32 Flags; 1265 + __le32 Reserved; 1266 + } __packed; 1267 + 1268 + 1269 + /* See MS-FSCC 2.3.20 */ 1270 + struct fsctl_get_integrity_information_rsp { 1271 + __le16 ChecksumAlgorithm; 1272 + __le16 Reserved; 1273 + __le32 Flags; 1274 + __le32 ChecksumChunkSizeInBytes; 1275 + __le32 ClusterSizeInBytes; 1276 + } __packed; 1277 + 1278 + /* See MS-FSCC 2.3.55 */ 1279 + struct fsctl_query_file_regions_req { 1280 + __le64 FileOffset; 1281 + __le64 Length; 1282 + __le32 DesiredUsage; 1283 + __le32 Reserved; 1284 + } __packed; 1285 + 1286 + /* DesiredUsage flags see MS-FSCC 2.3.56.1 */ 1287 + #define FILE_USAGE_INVALID_RANGE 0x00000000 1288 + #define FILE_USAGE_VALID_CACHED_DATA 0x00000001 1289 + #define FILE_USAGE_NONCACHED_DATA 0x00000002 1290 + 1291 + struct file_region_info { 1292 + __le64 FileOffset; 1293 + __le64 Length; 1294 + __le32 DesiredUsage; 1295 + __le32 Reserved; 1296 + } __packed; 1297 + 1298 + /* See MS-FSCC 2.3.56 */ 1299 + struct fsctl_query_file_region_rsp { 1300 + __le32 Flags; 1301 + __le32 TotalRegionEntryCount; 1302 + __le32 RegionEntryCount; 1303 + __u32 Reserved; 1304 + struct file_region_info Regions[]; 1305 + } __packed; 1306 + 1307 + /* See MS-FSCC 2.3.58 */ 1308 + struct fsctl_query_on_disk_vol_info_rsp { 1309 + __le64 DirectoryCount; 1310 + __le64 FileCount; 1311 + __le16 FsFormatMajVersion; 1312 + __le16 FsFormatMinVersion; 1313 + __u8 FsFormatName[24]; 1314 + __le64 FormatTime; 1315 + __le64 LastUpdateTime; 1316 + __u8 CopyrightInfo[68]; 1317 + __u8 AbstractInfo[68]; 1318 + __u8 FormatImplInfo[68]; 1319 + __u8 LastModifyImplInfo[68]; 1320 + } __packed; 1321 + 1322 + /* See MS-FSCC 2.3.73 */ 1323 + struct fsctl_set_integrity_information_req { 1324 + __le16 ChecksumAlgorithm; 1325 + __le16 Reserved; 1326 + __le32 Flags; 1327 + } __packed; 1328 + 1329 + /* See MS-FSCC 2.3.75 */ 1330 + struct fsctl_set_integrity_info_ex_req { 1331 + __u8 EnableIntegrity; 1332 + __u8 KeepState; 1333 + __u16 Reserved; 1334 + __le32 Flags; 1335 + __u8 Version; 1336 + __u8 Reserved2[7]; 1337 + } __packed; 1338 + 1339 + /* Integrity ChecksumAlgorithm choices for above */ 1340 + #define CHECKSUM_TYPE_NONE 0x0000 1341 + #define CHECKSUM_TYPE_CRC64 0x0002 1342 + #define CHECKSUM_TYPE_UNCHANGED 0xFFFF /* set only */ 1343 + 1344 + /* Integrity flags for above */ 1345 + #define FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF 0x00000001 1346 + 1247 1347 /* Reparse structures - see MS-FSCC 2.1.2 */ 1248 1348 1249 1349 /* struct fsctl_reparse_info_req is empty, only response structs (see below) */ ··· 1404 1304 __le16 Dialect; /* Dialect in use for the connection */ 1405 1305 } __packed; 1406 1306 1407 - struct duplicate_extents_to_file { 1408 - __u64 PersistentFileHandle; /* source file handle, opaque endianness */ 1409 - __u64 VolatileFileHandle; 1410 - __le64 SourceFileOffset; 1411 - __le64 TargetFileOffset; 1412 - __le64 ByteCount; /* Bytes to be copied */ 1413 - } __packed; 1414 1307 1415 1308 /* Possible InfoType values */ 1416 1309 #define SMB2_O_INFO_FILE 0x01 ··· 1512 1419 * PDU query infolevel structure definitions 1513 1420 */ 1514 1421 1422 + /* See MS-FSCC 2.3.52 */ 1515 1423 struct file_allocated_range_buffer { 1516 1424 __le64 file_offset; 1517 1425 __le64 length;
+6
fs/smbfs_common/smbfsctl.h
··· 88 88 #define FSCTL_READ_RAW_ENCRYPTED 0x000900E3 /* BB add struct */ 89 89 #define FSCTL_READ_FILE_USN_DATA 0x000900EB /* BB add struct */ 90 90 #define FSCTL_WRITE_USN_CLOSE_RECORD 0x000900EF /* BB add struct */ 91 + #define FSCTL_MARK_HANDLE 0x000900FC /* BB add struct */ 91 92 #define FSCTL_SIS_COPYFILE 0x00090100 /* BB add struct */ 92 93 #define FSCTL_RECALL_FILE 0x00090117 /* BB add struct */ 93 94 #define FSCTL_QUERY_SPARING_INFO 0x00090138 /* BB add struct */ 95 + #define FSCTL_QUERY_ON_DISK_VOLUME_INFO 0x0009013C 94 96 #define FSCTL_SET_ZERO_ON_DEALLOC 0x00090194 /* BB add struct */ 95 97 #define FSCTL_SET_SHORT_NAME_BEHAVIOR 0x000901B4 /* BB add struct */ 96 98 #define FSCTL_GET_INTEGRITY_INFORMATION 0x0009027C 99 + #define FSCTL_QUERY_FILE_REGIONS 0x00090284 97 100 #define FSCTL_GET_REFS_VOLUME_DATA 0x000902D8 /* See MS-FSCC 2.3.24 */ 98 101 #define FSCTL_SET_INTEGRITY_INFORMATION_EXT 0x00090380 99 102 #define FSCTL_GET_RETRIEVAL_POINTERS_AND_REFCOUNT 0x000903d3 100 103 #define FSCTL_GET_RETRIEVAL_POINTER_COUNT 0x0009042b 101 104 #define FSCTL_REFS_STREAM_SNAPSHOT_MANAGEMENT 0x00090440 102 105 #define FSCTL_QUERY_ALLOCATED_RANGES 0x000940CF 106 + #define FSCTL_OFFLOAD_READ 0x00094264 /* BB add struct */ 107 + #define FSCTL_OFFLOAD_WRITE 0x00098268 /* BB add struct */ 103 108 #define FSCTL_SET_DEFECT_MANAGEMENT 0x00098134 /* BB add struct */ 104 109 #define FSCTL_FILE_LEVEL_TRIM 0x00098208 /* BB add struct */ 105 110 #define FSCTL_DUPLICATE_EXTENTS_TO_FILE 0x00098344 111 + #define FSCTL_DUPLICATE_EXTENTS_TO_FILE_EX 0x000983E8 106 112 #define FSCTL_SIS_LINK_FILES 0x0009C104 107 113 #define FSCTL_SET_INTEGRITY_INFORMATION 0x0009C280 108 114 #define FSCTL_PIPE_PEEK 0x0011400C /* BB add struct */