Commit 7dcc82c2 authored by Steve French's avatar Steve French
Browse files

smb3: improve handling of share deleted (and share recreated)



When a share is deleted, returning EIO is confusing and no useful
information is logged.  Improve the handling of this case by
at least logging a better error for this (and also mapping the error
differently to EREMCHG).  See e.g. the new messages that would be logged:

[55243.639530] server share \\192.168.1.219\scratch deleted
[55243.642568] CIFS VFS: \\192.168.1.219\scratch BAD_NETWORK_NAME: \\192.168.1.219\scratch

In addition for the case where a share is deleted and then recreated
with the same name, have now fixed that so it works. This is sometimes
done for example, because the admin had to move a share to a different,
bigger local drive when a share is running low on space.

Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Reviewed-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
parent 1b63f184
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -335,6 +335,12 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
		cifsFileInfo_put(cfile);
		cifsFileInfo_put(cfile);


	SMB2_open_free(&rqst[0]);
	SMB2_open_free(&rqst[0]);
	if (rc == -EREMCHG) {
		printk_once(KERN_WARNING "server share %s deleted\n",
			    tcon->treeName);
		tcon->need_reconnect = true;
	}

	switch (command) {
	switch (command) {
	case SMB2_OP_QUERY_INFO:
	case SMB2_OP_QUERY_INFO:
		if (rc == 0) {
		if (rc == 0) {
+1 −1
Original line number Original line Diff line number Diff line
@@ -511,7 +511,7 @@ static const struct status_to_posix_error smb2_error_map_table[] = {
	{STATUS_PRINT_QUEUE_FULL, -EIO, "STATUS_PRINT_QUEUE_FULL"},
	{STATUS_PRINT_QUEUE_FULL, -EIO, "STATUS_PRINT_QUEUE_FULL"},
	{STATUS_NO_SPOOL_SPACE, -EIO, "STATUS_NO_SPOOL_SPACE"},
	{STATUS_NO_SPOOL_SPACE, -EIO, "STATUS_NO_SPOOL_SPACE"},
	{STATUS_PRINT_CANCELLED, -EIO, "STATUS_PRINT_CANCELLED"},
	{STATUS_PRINT_CANCELLED, -EIO, "STATUS_PRINT_CANCELLED"},
	{STATUS_NETWORK_NAME_DELETED, -EIO, "STATUS_NETWORK_NAME_DELETED"},
	{STATUS_NETWORK_NAME_DELETED, -EREMCHG, "STATUS_NETWORK_NAME_DELETED"},
	{STATUS_NETWORK_ACCESS_DENIED, -EACCES, "STATUS_NETWORK_ACCESS_DENIED"},
	{STATUS_NETWORK_ACCESS_DENIED, -EACCES, "STATUS_NETWORK_ACCESS_DENIED"},
	{STATUS_BAD_DEVICE_TYPE, -EIO, "STATUS_BAD_DEVICE_TYPE"},
	{STATUS_BAD_DEVICE_TYPE, -EIO, "STATUS_BAD_DEVICE_TYPE"},
	{STATUS_BAD_NETWORK_NAME, -ENOENT, "STATUS_BAD_NETWORK_NAME"},
	{STATUS_BAD_NETWORK_NAME, -ENOENT, "STATUS_BAD_NETWORK_NAME"},
+12 −1
Original line number Original line Diff line number Diff line
@@ -741,8 +741,14 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)


	/* Cached root is still invalid, continue normaly */
	/* Cached root is still invalid, continue normaly */


	if (rc)
	if (rc) {
		if (rc == -EREMCHG) {
			tcon->need_reconnect = true;
			printk_once(KERN_WARNING "server share %s deleted\n",
				    tcon->treeName);
		}
		goto oshr_exit;
		goto oshr_exit;
	}


	o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
	o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
	oparms.fid->persistent_fid = o_rsp->PersistentFileId;
	oparms.fid->persistent_fid = o_rsp->PersistentFileId;
@@ -2237,6 +2243,11 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
				resp_buftype, rsp_iov);
				resp_buftype, rsp_iov);
	if (rc) {
	if (rc) {
		free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
		free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
		if (rc == -EREMCHG) {
			tcon->need_reconnect = true;
			printk_once(KERN_WARNING "server share %s deleted\n",
				    tcon->treeName);
		}
		goto qic_exit;
		goto qic_exit;
	}
	}
	*rsp = rsp_iov[1];
	*rsp = rsp_iov[1];
+5 −0
Original line number Original line Diff line number Diff line
@@ -2595,6 +2595,11 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
		}
		}
		trace_smb3_open_err(xid, tcon->tid, ses->Suid,
		trace_smb3_open_err(xid, tcon->tid, ses->Suid,
				    oparms->create_options, oparms->desired_access, rc);
				    oparms->create_options, oparms->desired_access, rc);
		if (rc == -EREMCHG) {
			printk_once(KERN_WARNING "server share %s deleted\n",
				    tcon->treeName);
			tcon->need_reconnect = true;
		}
		goto creat_exit;
		goto creat_exit;
	} else
	} else
		trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid,
		trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid,