Commit ca00c700 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull smb client fixes from Steve French:

 - reconnect fix

 - multichannel channel selection fix

 - minor mount warning fix

 - reparse point fix

 - null pointer check improvement

* tag '6.8-rc3-smb3-client-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  smb3: clarify mount warning
  cifs: handle cases where multiple sessions share connection
  cifs: change tcon status when need_reconnect is set on it
  smb: client: set correct d_type for reparse points under DFS mounts
  smb3: add missing null server pointer check
parents e1e3f530 a5cc98eb
...@@ -233,6 +233,12 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server, ...@@ -233,6 +233,12 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) { list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) {
/* check if iface is still active */ /* check if iface is still active */
spin_lock(&ses->chan_lock); spin_lock(&ses->chan_lock);
if (cifs_ses_get_chan_index(ses, server) ==
CIFS_INVAL_CHAN_INDEX) {
spin_unlock(&ses->chan_lock);
continue;
}
if (!cifs_chan_is_iface_active(ses, server)) { if (!cifs_chan_is_iface_active(ses, server)) {
spin_unlock(&ses->chan_lock); spin_unlock(&ses->chan_lock);
cifs_chan_update_iface(ses, server); cifs_chan_update_iface(ses, server);
...@@ -4228,6 +4234,11 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru ...@@ -4228,6 +4234,11 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
/* only send once per connect */ /* only send once per connect */
spin_lock(&tcon->tc_lock); spin_lock(&tcon->tc_lock);
/* if tcon is marked for needing reconnect, update state */
if (tcon->need_reconnect)
tcon->status = TID_NEED_TCON;
if (tcon->status == TID_GOOD) { if (tcon->status == TID_GOOD) {
spin_unlock(&tcon->tc_lock); spin_unlock(&tcon->tc_lock);
return 0; return 0;
......
...@@ -565,6 +565,11 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru ...@@ -565,6 +565,11 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
/* only send once per connect */ /* only send once per connect */
spin_lock(&tcon->tc_lock); spin_lock(&tcon->tc_lock);
/* if tcon is marked for needing reconnect, update state */
if (tcon->need_reconnect)
tcon->status = TID_NEED_TCON;
if (tcon->status == TID_GOOD) { if (tcon->status == TID_GOOD) {
spin_unlock(&tcon->tc_lock); spin_unlock(&tcon->tc_lock);
return 0; return 0;
...@@ -625,8 +630,8 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru ...@@ -625,8 +630,8 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru
spin_lock(&tcon->tc_lock); spin_lock(&tcon->tc_lock);
if (tcon->status == TID_IN_TCON) if (tcon->status == TID_IN_TCON)
tcon->status = TID_GOOD; tcon->status = TID_GOOD;
spin_unlock(&tcon->tc_lock);
tcon->need_reconnect = false; tcon->need_reconnect = false;
spin_unlock(&tcon->tc_lock);
} }
return rc; return rc;
......
...@@ -175,6 +175,9 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon) ...@@ -175,6 +175,9 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
/* only send once per connect */ /* only send once per connect */
spin_lock(&tcon->tc_lock); spin_lock(&tcon->tc_lock);
if (tcon->need_reconnect)
tcon->status = TID_NEED_RECON;
if (tcon->status != TID_NEED_RECON) { if (tcon->status != TID_NEED_RECON) {
spin_unlock(&tcon->tc_lock); spin_unlock(&tcon->tc_lock);
return; return;
......
...@@ -211,7 +211,7 @@ cifs_parse_security_flavors(struct fs_context *fc, char *value, struct smb3_fs_c ...@@ -211,7 +211,7 @@ cifs_parse_security_flavors(struct fs_context *fc, char *value, struct smb3_fs_c
switch (match_token(value, cifs_secflavor_tokens, args)) { switch (match_token(value, cifs_secflavor_tokens, args)) {
case Opt_sec_krb5p: case Opt_sec_krb5p:
cifs_errorf(fc, "sec=krb5p is not supported!\n"); cifs_errorf(fc, "sec=krb5p is not supported. Use sec=krb5,seal instead\n");
return 1; return 1;
case Opt_sec_krb5i: case Opt_sec_krb5i:
ctx->sign = true; ctx->sign = true;
......
...@@ -307,14 +307,16 @@ cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, ...@@ -307,14 +307,16 @@ cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info,
} }
static void cifs_fulldir_info_to_fattr(struct cifs_fattr *fattr, static void cifs_fulldir_info_to_fattr(struct cifs_fattr *fattr,
SEARCH_ID_FULL_DIR_INFO *info, const void *info,
struct cifs_sb_info *cifs_sb) struct cifs_sb_info *cifs_sb)
{ {
const FILE_FULL_DIRECTORY_INFO *di = info;
__dir_info_to_fattr(fattr, info); __dir_info_to_fattr(fattr, info);
/* See MS-FSCC 2.4.19 FileIdFullDirectoryInformation */ /* See MS-FSCC 2.4.14, 2.4.19 */
if (fattr->cf_cifsattrs & ATTR_REPARSE) if (fattr->cf_cifsattrs & ATTR_REPARSE)
fattr->cf_cifstag = le32_to_cpu(info->EaSize); fattr->cf_cifstag = le32_to_cpu(di->EaSize);
cifs_fill_common_info(fattr, cifs_sb); cifs_fill_common_info(fattr, cifs_sb);
} }
...@@ -396,7 +398,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file, ...@@ -396,7 +398,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file,
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
} else /* not srvinos - BB fixme add check for backlevel? */ { } else /* not srvinos - BB fixme add check for backlevel? */ {
cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; cifsFile->srch_inf.info_level = SMB_FIND_FILE_FULL_DIRECTORY_INFO;
} }
search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME; search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME;
...@@ -987,10 +989,9 @@ static int cifs_filldir(char *find_entry, struct file *file, ...@@ -987,10 +989,9 @@ static int cifs_filldir(char *find_entry, struct file *file,
(FIND_FILE_STANDARD_INFO *)find_entry, (FIND_FILE_STANDARD_INFO *)find_entry,
cifs_sb); cifs_sb);
break; break;
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
case SMB_FIND_FILE_ID_FULL_DIR_INFO: case SMB_FIND_FILE_ID_FULL_DIR_INFO:
cifs_fulldir_info_to_fattr(&fattr, cifs_fulldir_info_to_fattr(&fattr, find_entry, cifs_sb);
(SEARCH_ID_FULL_DIR_INFO *)find_entry,
cifs_sb);
break; break;
default: default:
cifs_dir_info_to_fattr(&fattr, cifs_dir_info_to_fattr(&fattr,
......
...@@ -76,7 +76,7 @@ cifs_ses_get_chan_index(struct cifs_ses *ses, ...@@ -76,7 +76,7 @@ cifs_ses_get_chan_index(struct cifs_ses *ses,
unsigned int i; unsigned int i;
/* if the channel is waiting for termination */ /* if the channel is waiting for termination */
if (server->terminate) if (server && server->terminate)
return CIFS_INVAL_CHAN_INDEX; return CIFS_INVAL_CHAN_INDEX;
for (i = 0; i < ses->chan_count; i++) { for (i = 0; i < ses->chan_count; i++) {
...@@ -88,7 +88,6 @@ cifs_ses_get_chan_index(struct cifs_ses *ses, ...@@ -88,7 +88,6 @@ cifs_ses_get_chan_index(struct cifs_ses *ses,
if (server) if (server)
cifs_dbg(VFS, "unable to get chan index for server: 0x%llx", cifs_dbg(VFS, "unable to get chan index for server: 0x%llx",
server->conn_id); server->conn_id);
WARN_ON(1);
return CIFS_INVAL_CHAN_INDEX; return CIFS_INVAL_CHAN_INDEX;
} }
......
...@@ -5206,6 +5206,9 @@ int SMB2_query_directory_init(const unsigned int xid, ...@@ -5206,6 +5206,9 @@ int SMB2_query_directory_init(const unsigned int xid,
case SMB_FIND_FILE_POSIX_INFO: case SMB_FIND_FILE_POSIX_INFO:
req->FileInformationClass = SMB_FIND_FILE_POSIX_INFO; req->FileInformationClass = SMB_FIND_FILE_POSIX_INFO;
break; break;
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
req->FileInformationClass = FILE_FULL_DIRECTORY_INFORMATION;
break;
default: default:
cifs_tcon_dbg(VFS, "info level %u isn't supported\n", cifs_tcon_dbg(VFS, "info level %u isn't supported\n",
info_level); info_level);
...@@ -5275,6 +5278,9 @@ smb2_parse_query_directory(struct cifs_tcon *tcon, ...@@ -5275,6 +5278,9 @@ smb2_parse_query_directory(struct cifs_tcon *tcon,
/* note that posix payload are variable size */ /* note that posix payload are variable size */
info_buf_size = sizeof(struct smb2_posix_info); info_buf_size = sizeof(struct smb2_posix_info);
break; break;
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
info_buf_size = sizeof(FILE_FULL_DIRECTORY_INFO);
break;
default: default:
cifs_tcon_dbg(VFS, "info level %u isn't supported\n", cifs_tcon_dbg(VFS, "info level %u isn't supported\n",
srch_inf->info_level); srch_inf->info_level);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment