Commit 62345e48 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag '5.18-rc2-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs fixes from Steve French:

 - two fixes related to unmount

 - symlink overflow fix

 - minor netfs fix

 - improved tracing for crediting (flow control)

* tag '5.18-rc2-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: verify that tcon is valid before dereference in cifs_kill_sb
  cifs: potential buffer overflow in handling symlinks
  cifs: Split the smb3_add_credits tracepoint
  cifs: release cached dentries only if mount is complete
  cifs: Check the IOCB_DIRECT flag, not O_DIRECT
parents b3d4650d 8b6c5845
...@@ -266,22 +266,24 @@ static void cifs_kill_sb(struct super_block *sb) ...@@ -266,22 +266,24 @@ static void cifs_kill_sb(struct super_block *sb)
* before we kill the sb. * before we kill the sb.
*/ */
if (cifs_sb->root) { if (cifs_sb->root) {
for (node = rb_first(root); node; node = rb_next(node)) {
tlink = rb_entry(node, struct tcon_link, tl_rbnode);
tcon = tlink_tcon(tlink);
if (IS_ERR(tcon))
continue;
cfid = &tcon->crfid;
mutex_lock(&cfid->fid_mutex);
if (cfid->dentry) {
dput(cfid->dentry);
cfid->dentry = NULL;
}
mutex_unlock(&cfid->fid_mutex);
}
/* finally release root dentry */
dput(cifs_sb->root); dput(cifs_sb->root);
cifs_sb->root = NULL; cifs_sb->root = NULL;
} }
node = rb_first(root);
while (node != NULL) {
tlink = rb_entry(node, struct tcon_link, tl_rbnode);
tcon = tlink_tcon(tlink);
cfid = &tcon->crfid;
mutex_lock(&cfid->fid_mutex);
if (cfid->dentry) {
dput(cfid->dentry);
cfid->dentry = NULL;
}
mutex_unlock(&cfid->fid_mutex);
node = rb_next(node);
}
kill_anon_super(sb); kill_anon_super(sb);
cifs_umount(cifs_sb); cifs_umount(cifs_sb);
...@@ -944,7 +946,7 @@ cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter) ...@@ -944,7 +946,7 @@ cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
ssize_t rc; ssize_t rc;
struct inode *inode = file_inode(iocb->ki_filp); struct inode *inode = file_inode(iocb->ki_filp);
if (iocb->ki_filp->f_flags & O_DIRECT) if (iocb->ki_flags & IOCB_DIRECT)
return cifs_user_readv(iocb, iter); return cifs_user_readv(iocb, iter);
rc = cifs_revalidate_mapping(inode); rc = cifs_revalidate_mapping(inode);
......
...@@ -1049,7 +1049,7 @@ smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server) ...@@ -1049,7 +1049,7 @@ smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
spin_unlock(&server->req_lock); spin_unlock(&server->req_lock);
wake_up(&server->request_q); wake_up(&server->request_q);
trace_smb3_add_credits(server->CurrentMid, trace_smb3_hdr_credits(server->CurrentMid,
server->conn_id, server->hostname, scredits, server->conn_id, server->hostname, scredits,
le16_to_cpu(shdr->CreditRequest), in_flight); le16_to_cpu(shdr->CreditRequest), in_flight);
cifs_server_dbg(FYI, "%s: added %u credits total=%d\n", cifs_server_dbg(FYI, "%s: added %u credits total=%d\n",
......
...@@ -85,6 +85,9 @@ parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len, ...@@ -85,6 +85,9 @@ parse_mf_symlink(const u8 *buf, unsigned int buf_len, unsigned int *_link_len,
if (rc != 1) if (rc != 1)
return -EINVAL; return -EINVAL;
if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
return -EINVAL;
rc = symlink_hash(link_len, link_str, md5_hash); rc = symlink_hash(link_len, link_str, md5_hash);
if (rc) { if (rc) {
cifs_dbg(FYI, "%s: MD5 hash failure: %d\n", __func__, rc); cifs_dbg(FYI, "%s: MD5 hash failure: %d\n", __func__, rc);
......
...@@ -86,6 +86,9 @@ smb2_add_credits(struct TCP_Server_Info *server, ...@@ -86,6 +86,9 @@ smb2_add_credits(struct TCP_Server_Info *server,
if (*val > 65000) { if (*val > 65000) {
*val = 65000; /* Don't get near 64K credits, avoid srv bugs */ *val = 65000; /* Don't get near 64K credits, avoid srv bugs */
pr_warn_once("server overflowed SMB3 credits\n"); pr_warn_once("server overflowed SMB3 credits\n");
trace_smb3_overflow_credits(server->CurrentMid,
server->conn_id, server->hostname, *val,
add, server->in_flight);
} }
server->in_flight--; server->in_flight--;
if (server->in_flight == 0 && if (server->in_flight == 0 &&
...@@ -251,7 +254,7 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, ...@@ -251,7 +254,7 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size,
in_flight = server->in_flight; in_flight = server->in_flight;
spin_unlock(&server->req_lock); spin_unlock(&server->req_lock);
trace_smb3_add_credits(server->CurrentMid, trace_smb3_wait_credits(server->CurrentMid,
server->conn_id, server->hostname, scredits, -(credits->value), in_flight); server->conn_id, server->hostname, scredits, -(credits->value), in_flight);
cifs_dbg(FYI, "%s: removed %u credits total=%d\n", cifs_dbg(FYI, "%s: removed %u credits total=%d\n",
__func__, credits->value, scredits); __func__, credits->value, scredits);
...@@ -300,7 +303,7 @@ smb2_adjust_credits(struct TCP_Server_Info *server, ...@@ -300,7 +303,7 @@ smb2_adjust_credits(struct TCP_Server_Info *server,
spin_unlock(&server->req_lock); spin_unlock(&server->req_lock);
wake_up(&server->request_q); wake_up(&server->request_q);
trace_smb3_add_credits(server->CurrentMid, trace_smb3_adj_credits(server->CurrentMid,
server->conn_id, server->hostname, scredits, server->conn_id, server->hostname, scredits,
credits->value - new_val, in_flight); credits->value - new_val, in_flight);
cifs_dbg(FYI, "%s: adjust added %u credits total=%d\n", cifs_dbg(FYI, "%s: adjust added %u credits total=%d\n",
...@@ -2492,7 +2495,7 @@ smb2_is_status_pending(char *buf, struct TCP_Server_Info *server) ...@@ -2492,7 +2495,7 @@ smb2_is_status_pending(char *buf, struct TCP_Server_Info *server)
spin_unlock(&server->req_lock); spin_unlock(&server->req_lock);
wake_up(&server->request_q); wake_up(&server->request_q);
trace_smb3_add_credits(server->CurrentMid, trace_smb3_pend_credits(server->CurrentMid,
server->conn_id, server->hostname, scredits, server->conn_id, server->hostname, scredits,
le16_to_cpu(shdr->CreditRequest), in_flight); le16_to_cpu(shdr->CreditRequest), in_flight);
cifs_dbg(FYI, "%s: status pending add %u credits total=%d\n", cifs_dbg(FYI, "%s: status pending add %u credits total=%d\n",
......
...@@ -1006,6 +1006,13 @@ DEFINE_SMB3_CREDIT_EVENT(credit_timeout); ...@@ -1006,6 +1006,13 @@ DEFINE_SMB3_CREDIT_EVENT(credit_timeout);
DEFINE_SMB3_CREDIT_EVENT(insufficient_credits); DEFINE_SMB3_CREDIT_EVENT(insufficient_credits);
DEFINE_SMB3_CREDIT_EVENT(too_many_credits); DEFINE_SMB3_CREDIT_EVENT(too_many_credits);
DEFINE_SMB3_CREDIT_EVENT(add_credits); DEFINE_SMB3_CREDIT_EVENT(add_credits);
DEFINE_SMB3_CREDIT_EVENT(adj_credits);
DEFINE_SMB3_CREDIT_EVENT(hdr_credits);
DEFINE_SMB3_CREDIT_EVENT(nblk_credits);
DEFINE_SMB3_CREDIT_EVENT(pend_credits);
DEFINE_SMB3_CREDIT_EVENT(wait_credits);
DEFINE_SMB3_CREDIT_EVENT(waitff_credits);
DEFINE_SMB3_CREDIT_EVENT(overflow_credits);
DEFINE_SMB3_CREDIT_EVENT(set_credits); DEFINE_SMB3_CREDIT_EVENT(set_credits);
#endif /* _CIFS_TRACE_H */ #endif /* _CIFS_TRACE_H */
......
...@@ -542,7 +542,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, ...@@ -542,7 +542,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits,
in_flight = server->in_flight; in_flight = server->in_flight;
spin_unlock(&server->req_lock); spin_unlock(&server->req_lock);
trace_smb3_add_credits(server->CurrentMid, trace_smb3_nblk_credits(server->CurrentMid,
server->conn_id, server->hostname, scredits, -1, in_flight); server->conn_id, server->hostname, scredits, -1, in_flight);
cifs_dbg(FYI, "%s: remove %u credits total=%d\n", cifs_dbg(FYI, "%s: remove %u credits total=%d\n",
__func__, 1, scredits); __func__, 1, scredits);
...@@ -648,7 +648,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, ...@@ -648,7 +648,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits,
in_flight = server->in_flight; in_flight = server->in_flight;
spin_unlock(&server->req_lock); spin_unlock(&server->req_lock);
trace_smb3_add_credits(server->CurrentMid, trace_smb3_waitff_credits(server->CurrentMid,
server->conn_id, server->hostname, scredits, server->conn_id, server->hostname, scredits,
-(num_credits), in_flight); -(num_credits), in_flight);
cifs_dbg(FYI, "%s: remove %u credits total=%d\n", cifs_dbg(FYI, "%s: remove %u credits total=%d\n",
......
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