Commit 88c5060d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull cifs fixes from Steve French:
 "Four fixes, two of them for stable:

   - fcollapse fix

   - reconnect lock fix

   - DFS oops fix

   - minor cleanup patch"

* tag '5.18-rc3-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: destage any unwritten data to the server before calling copychunk_write
  cifs: use correct lock type in cifs_reconnect()
  cifs: fix NULL ptr dereference in refresh_mounts()
  cifs: Use kzalloc instead of kmalloc/memset
parents 279b83c6 f5d0f921
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -534,12 +534,19 @@ int cifs_reconnect(struct TCP_Server_Info *server, bool mark_smb_session)
{
	/* If tcp session is not an dfs connection, then reconnect to last target server */
	spin_lock(&cifs_tcp_ses_lock);
	if (!server->is_dfs_conn || !server->origin_fullpath || !server->leaf_fullpath) {
	if (!server->is_dfs_conn) {
		spin_unlock(&cifs_tcp_ses_lock);
		return __cifs_reconnect(server, mark_smb_session);
	}
	spin_unlock(&cifs_tcp_ses_lock);

	mutex_lock(&server->refpath_lock);
	if (!server->origin_fullpath || !server->leaf_fullpath) {
		mutex_unlock(&server->refpath_lock);
		return __cifs_reconnect(server, mark_smb_session);
	}
	mutex_unlock(&server->refpath_lock);

	return reconnect_dfs_server(server);
}
#else
@@ -3675,9 +3682,11 @@ static void setup_server_referral_paths(struct mount_ctx *mnt_ctx)
{
	struct TCP_Server_Info *server = mnt_ctx->server;

	mutex_lock(&server->refpath_lock);
	server->origin_fullpath = mnt_ctx->origin_fullpath;
	server->leaf_fullpath = mnt_ctx->leaf_fullpath;
	server->current_fullpath = mnt_ctx->leaf_fullpath;
	mutex_unlock(&server->refpath_lock);
	mnt_ctx->origin_fullpath = mnt_ctx->leaf_fullpath = NULL;
}

+12 −7
Original line number Diff line number Diff line
@@ -1422,11 +1422,13 @@ static int refresh_tcon(struct cifs_ses **sessions, struct cifs_tcon *tcon, bool
	struct TCP_Server_Info *server = tcon->ses->server;

	mutex_lock(&server->refpath_lock);
	if (strcasecmp(server->leaf_fullpath, server->origin_fullpath))
	if (server->origin_fullpath) {
		if (server->leaf_fullpath && strcasecmp(server->leaf_fullpath,
							server->origin_fullpath))
			__refresh_tcon(server->leaf_fullpath + 1, sessions, tcon, force_refresh);
	mutex_unlock(&server->refpath_lock);

		__refresh_tcon(server->origin_fullpath + 1, sessions, tcon, force_refresh);
	}
	mutex_unlock(&server->refpath_lock);

	return 0;
}
@@ -1530,11 +1532,14 @@ static void refresh_mounts(struct cifs_ses **sessions)
		list_del_init(&tcon->ulist);

		mutex_lock(&server->refpath_lock);
		if (strcasecmp(server->leaf_fullpath, server->origin_fullpath))
		if (server->origin_fullpath) {
			if (server->leaf_fullpath && strcasecmp(server->leaf_fullpath,
								server->origin_fullpath))
				__refresh_tcon(server->leaf_fullpath + 1, sessions, tcon, false);
			__refresh_tcon(server->origin_fullpath + 1, sessions, tcon, false);
		}
		mutex_unlock(&server->refpath_lock);

		__refresh_tcon(server->origin_fullpath + 1, sessions, tcon, false);
		cifs_put_tcon(tcon);
	}
}
+8 −0
Original line number Diff line number Diff line
@@ -1858,9 +1858,17 @@ smb2_copychunk_range(const unsigned int xid,
	int chunks_copied = 0;
	bool chunk_sizes_updated = false;
	ssize_t bytes_written, total_bytes_written = 0;
	struct inode *inode;

	pcchunk = kmalloc(sizeof(struct copychunk_ioctl), GFP_KERNEL);

	/*
	 * We need to flush all unwritten data before we can send the
	 * copychunk ioctl to the server.
	 */
	inode = d_inode(trgtfile->dentry);
	filemap_write_and_wait(inode->i_mapping);

	if (pcchunk == NULL)
		return -ENOMEM;

+1 −2
Original line number Diff line number Diff line
@@ -464,13 +464,12 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
		return -EIO;
	}

	tr_hdr = kmalloc(sizeof(*tr_hdr), GFP_NOFS);
	tr_hdr = kzalloc(sizeof(*tr_hdr), GFP_NOFS);
	if (!tr_hdr)
		return -ENOMEM;

	memset(&cur_rqst[0], 0, sizeof(cur_rqst));
	memset(&iov, 0, sizeof(iov));
	memset(tr_hdr, 0, sizeof(*tr_hdr));

	iov.iov_base = tr_hdr;
	iov.iov_len = sizeof(*tr_hdr);