Skip to content

Commit bf27246

Browse files
committed
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 ...
2 parents aef1ff1 + 44a4808 commit bf27246

24 files changed

+559
-189
lines changed

fs/cifs/cifs_debug.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
116116
tcon->ses->server->ops->dump_share_caps(m, tcon);
117117
if (tcon->use_witness)
118118
seq_puts(m, " Witness");
119-
119+
if (tcon->broken_sparse_sup)
120+
seq_puts(m, " nosparse");
120121
if (tcon->need_reconnect)
121122
seq_puts(m, "\tDISCONNECTED ");
122123
seq_putc(m, '\n');
@@ -386,7 +387,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
386387
(ses->serverNOS == NULL)) {
387388
seq_printf(m, "\n\t%d) Address: %s Uses: %d Capability: 0x%x\tSession Status: %d ",
388389
i, ses->ip_addr, ses->ses_count,
389-
ses->capabilities, ses->status);
390+
ses->capabilities, ses->ses_status);
390391
if (ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST)
391392
seq_printf(m, "Guest ");
392393
else if (ses->session_flags & SMB2_SESSION_FLAG_IS_NULL)
@@ -398,7 +399,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
398399
"\n\tSMB session status: %d ",
399400
i, ses->ip_addr, ses->serverDomain,
400401
ses->ses_count, ses->serverOS, ses->serverNOS,
401-
ses->capabilities, ses->status);
402+
ses->capabilities, ses->ses_status);
402403
}
403404

404405
seq_printf(m, "\n\tSecurity type: %s ",
@@ -418,6 +419,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
418419
spin_lock(&ses->chan_lock);
419420
if (CIFS_CHAN_NEEDS_RECONNECT(ses, 0))
420421
seq_puts(m, "\tPrimary channel: DISCONNECTED ");
422+
if (CIFS_CHAN_IN_RECONNECT(ses, 0))
423+
seq_puts(m, "\t[RECONNECTING] ");
421424

422425
if (ses->chan_count > 1) {
423426
seq_printf(m, "\n\n\tExtra Channels: %zu ",
@@ -426,6 +429,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
426429
cifs_dump_channel(m, j, &ses->chans[j]);
427430
if (CIFS_CHAN_NEEDS_RECONNECT(ses, j))
428431
seq_puts(m, "\tDISCONNECTED ");
432+
if (CIFS_CHAN_IN_RECONNECT(ses, j))
433+
seq_puts(m, "\t[RECONNECTING] ");
429434
}
430435
}
431436
spin_unlock(&ses->chan_lock);

fs/cifs/cifsfs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
582582
seq_puts(s, ",nocase");
583583
if (tcon->nodelete)
584584
seq_puts(s, ",nodelete");
585+
if (cifs_sb->ctx->no_sparse)
586+
seq_puts(s, ",nosparse");
585587
if (tcon->local_lease)
586588
seq_puts(s, ",locallease");
587589
if (tcon->retry)

fs/cifs/cifsglob.h

Lines changed: 88 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -106,16 +106,23 @@
106106
* CIFS vfs client Status information (based on what we know.)
107107
*/
108108

109-
/* associated with each tcp and smb session */
109+
/* associated with each connection */
110110
enum statusEnum {
111111
CifsNew = 0,
112112
CifsGood,
113113
CifsExiting,
114114
CifsNeedReconnect,
115115
CifsNeedNegotiate,
116116
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
119126
};
120127

121128
/* associated with each tree connection to the server */
@@ -915,6 +922,7 @@ struct cifs_server_iface {
915922
};
916923

917924
struct cifs_chan {
925+
unsigned int in_reconnect : 1; /* if session setup in progress for this channel */
918926
struct TCP_Server_Info *server;
919927
__u8 signkey[SMB3_SIGN_KEY_SIZE];
920928
};
@@ -930,7 +938,7 @@ struct cifs_ses {
930938
struct mutex session_mutex;
931939
struct TCP_Server_Info *server; /* pointer to server info */
932940
int ses_count; /* reference counter */
933-
enum statusEnum status; /* updates protected by cifs_tcp_ses_lock */
941+
enum ses_status_enum ses_status; /* updates protected by cifs_tcp_ses_lock */
934942
unsigned overrideSecFlg; /* if non-zero override global sec flags */
935943
char *serverOS; /* name of operating system underlying server */
936944
char *serverNOS; /* name of network operating system of server */
@@ -944,7 +952,7 @@ struct cifs_ses {
944952
and after mount option parsing we fill it */
945953
char *domainName;
946954
char *password;
947-
char *workstation_name;
955+
char workstation_name[CIFS_MAX_WORKSTATION_LEN];
948956
struct session_key auth_key;
949957
struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */
950958
enum securityEnum sectype; /* what security flavor was specified? */
@@ -977,12 +985,16 @@ struct cifs_ses {
977985
#define CIFS_MAX_CHANNELS 16
978986
#define CIFS_ALL_CHANNELS_SET(ses) \
979987
((1UL << (ses)->chan_count) - 1)
988+
#define CIFS_ALL_CHANS_GOOD(ses) \
989+
(!(ses)->chans_need_reconnect)
980990
#define CIFS_ALL_CHANS_NEED_RECONNECT(ses) \
981991
((ses)->chans_need_reconnect == CIFS_ALL_CHANNELS_SET(ses))
982992
#define CIFS_SET_ALL_CHANS_NEED_RECONNECT(ses) \
983993
((ses)->chans_need_reconnect = CIFS_ALL_CHANNELS_SET(ses))
984994
#define CIFS_CHAN_NEEDS_RECONNECT(ses, index) \
985995
test_bit((index), &(ses)->chans_need_reconnect)
996+
#define CIFS_CHAN_IN_RECONNECT(ses, index) \
997+
((ses)->chans[(index)].in_reconnect)
986998

987999
struct cifs_chan chans[CIFS_MAX_CHANNELS];
9881000
size_t chan_count;
@@ -1009,6 +1021,58 @@ cap_unix(struct cifs_ses *ses)
10091021
return ses->server->vals->cap_unix & ses->capabilities;
10101022
}
10111023

1024+
/*
1025+
* common struct for holding inode info when searching for or updating an
1026+
* inode with new info
1027+
*/
1028+
1029+
#define CIFS_FATTR_DFS_REFERRAL 0x1
1030+
#define CIFS_FATTR_DELETE_PENDING 0x2
1031+
#define CIFS_FATTR_NEED_REVAL 0x4
1032+
#define CIFS_FATTR_INO_COLLISION 0x8
1033+
#define CIFS_FATTR_UNKNOWN_NLINK 0x10
1034+
#define CIFS_FATTR_FAKE_ROOT_INO 0x20
1035+
1036+
struct cifs_fattr {
1037+
u32 cf_flags;
1038+
u32 cf_cifsattrs;
1039+
u64 cf_uniqueid;
1040+
u64 cf_eof;
1041+
u64 cf_bytes;
1042+
u64 cf_createtime;
1043+
kuid_t cf_uid;
1044+
kgid_t cf_gid;
1045+
umode_t cf_mode;
1046+
dev_t cf_rdev;
1047+
unsigned int cf_nlink;
1048+
unsigned int cf_dtype;
1049+
struct timespec64 cf_atime;
1050+
struct timespec64 cf_mtime;
1051+
struct timespec64 cf_ctime;
1052+
u32 cf_cifstag;
1053+
};
1054+
1055+
struct cached_dirent {
1056+
struct list_head entry;
1057+
char *name;
1058+
int namelen;
1059+
loff_t pos;
1060+
1061+
struct cifs_fattr fattr;
1062+
};
1063+
1064+
struct cached_dirents {
1065+
bool is_valid:1;
1066+
bool is_failed:1;
1067+
struct dir_context *ctx; /*
1068+
* Only used to make sure we only take entries
1069+
* from a single context. Never dereferenced.
1070+
*/
1071+
struct mutex de_mutex;
1072+
int pos; /* Expected ctx->pos */
1073+
struct list_head entries;
1074+
};
1075+
10121076
struct cached_fid {
10131077
bool is_valid:1; /* Do we have a useable root fid */
10141078
bool file_all_info_is_valid:1;
@@ -1021,6 +1085,7 @@ struct cached_fid {
10211085
struct dentry *dentry;
10221086
struct work_struct lease_break;
10231087
struct smb2_file_all_info file_all_info;
1088+
struct cached_dirents dirents;
10241089
};
10251090

10261091
/*
@@ -1641,37 +1706,6 @@ struct file_list {
16411706
struct cifsFileInfo *cfile;
16421707
};
16431708

1644-
/*
1645-
* common struct for holding inode info when searching for or updating an
1646-
* inode with new info
1647-
*/
1648-
1649-
#define CIFS_FATTR_DFS_REFERRAL 0x1
1650-
#define CIFS_FATTR_DELETE_PENDING 0x2
1651-
#define CIFS_FATTR_NEED_REVAL 0x4
1652-
#define CIFS_FATTR_INO_COLLISION 0x8
1653-
#define CIFS_FATTR_UNKNOWN_NLINK 0x10
1654-
#define CIFS_FATTR_FAKE_ROOT_INO 0x20
1655-
1656-
struct cifs_fattr {
1657-
u32 cf_flags;
1658-
u32 cf_cifsattrs;
1659-
u64 cf_uniqueid;
1660-
u64 cf_eof;
1661-
u64 cf_bytes;
1662-
u64 cf_createtime;
1663-
kuid_t cf_uid;
1664-
kgid_t cf_gid;
1665-
umode_t cf_mode;
1666-
dev_t cf_rdev;
1667-
unsigned int cf_nlink;
1668-
unsigned int cf_dtype;
1669-
struct timespec64 cf_atime;
1670-
struct timespec64 cf_mtime;
1671-
struct timespec64 cf_ctime;
1672-
u32 cf_cifstag;
1673-
};
1674-
16751709
static inline void free_dfs_info_param(struct dfs_info3_param *param)
16761710
{
16771711
if (param) {
@@ -1979,4 +2013,22 @@ static inline bool cifs_is_referral_server(struct cifs_tcon *tcon,
19792013
return is_tcon_dfs(tcon) || (ref && (ref->flags & DFSREF_REFERRAL_SERVER));
19802014
}
19812015

2016+
static inline u64 cifs_flock_len(struct file_lock *fl)
2017+
{
2018+
return fl->fl_end == OFFSET_MAX ? 0 : fl->fl_end - fl->fl_start + 1;
2019+
}
2020+
2021+
static inline size_t ntlmssp_workstation_name_size(const struct cifs_ses *ses)
2022+
{
2023+
if (WARN_ON_ONCE(!ses || !ses->server))
2024+
return 0;
2025+
/*
2026+
* Make workstation name no more than 15 chars when using insecure dialects as some legacy
2027+
* servers do require it during NTLMSSP.
2028+
*/
2029+
if (ses->server->dialect <= SMB20_PROT_ID)
2030+
return min_t(size_t, sizeof(ses->workstation_name), RFC1001_NAME_LEN_WITH_NULL);
2031+
return sizeof(ses->workstation_name);
2032+
}
2033+
19822034
#endif /* _CIFS_GLOB_H */

fs/cifs/cifsproto.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,15 @@ unsigned int
619619
cifs_ses_get_chan_index(struct cifs_ses *ses,
620620
struct TCP_Server_Info *server);
621621
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
622631
cifs_chan_set_need_reconnect(struct cifs_ses *ses,
623632
struct TCP_Server_Info *server);
624633
void

fs/cifs/cifssmb.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
7575

7676
/* only send once per connect */
7777
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)) {
7979
spin_unlock(&cifs_tcp_ses_lock);
8080
return;
8181
}
@@ -2558,7 +2558,8 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
25582558

25592559
pLockData->fl_start = le64_to_cpu(parm_data->start);
25602560
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);
25622563
pLockData->fl_pid = -le32_to_cpu(parm_data->pid);
25632564
}
25642565
}

0 commit comments

Comments
 (0)