Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Steve French <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>

+24 -2
+6
fs/cifs/smb2inode.c
··· 335 335 cifsFileInfo_put(cfile); 336 336 337 337 SMB2_open_free(&rqst[0]); 338 + if (rc == -EREMCHG) { 339 + printk_once(KERN_WARNING "server share %s deleted\n", 340 + tcon->treeName); 341 + tcon->need_reconnect = true; 342 + } 343 + 338 344 switch (command) { 339 345 case SMB2_OP_QUERY_INFO: 340 346 if (rc == 0) {
+1 -1
fs/cifs/smb2maperror.c
··· 511 511 {STATUS_PRINT_QUEUE_FULL, -EIO, "STATUS_PRINT_QUEUE_FULL"}, 512 512 {STATUS_NO_SPOOL_SPACE, -EIO, "STATUS_NO_SPOOL_SPACE"}, 513 513 {STATUS_PRINT_CANCELLED, -EIO, "STATUS_PRINT_CANCELLED"}, 514 - {STATUS_NETWORK_NAME_DELETED, -EIO, "STATUS_NETWORK_NAME_DELETED"}, 514 + {STATUS_NETWORK_NAME_DELETED, -EREMCHG, "STATUS_NETWORK_NAME_DELETED"}, 515 515 {STATUS_NETWORK_ACCESS_DENIED, -EACCES, "STATUS_NETWORK_ACCESS_DENIED"}, 516 516 {STATUS_BAD_DEVICE_TYPE, -EIO, "STATUS_BAD_DEVICE_TYPE"}, 517 517 {STATUS_BAD_NETWORK_NAME, -ENOENT, "STATUS_BAD_NETWORK_NAME"},
+12 -1
fs/cifs/smb2ops.c
··· 741 741 742 742 /* Cached root is still invalid, continue normaly */ 743 743 744 - if (rc) 744 + if (rc) { 745 + if (rc == -EREMCHG) { 746 + tcon->need_reconnect = true; 747 + printk_once(KERN_WARNING "server share %s deleted\n", 748 + tcon->treeName); 749 + } 745 750 goto oshr_exit; 751 + } 746 752 747 753 o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base; 748 754 oparms.fid->persistent_fid = o_rsp->PersistentFileId; ··· 2243 2237 resp_buftype, rsp_iov); 2244 2238 if (rc) { 2245 2239 free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); 2240 + if (rc == -EREMCHG) { 2241 + tcon->need_reconnect = true; 2242 + printk_once(KERN_WARNING "server share %s deleted\n", 2243 + tcon->treeName); 2244 + } 2246 2245 goto qic_exit; 2247 2246 } 2248 2247 *rsp = rsp_iov[1];
+5
fs/cifs/smb2pdu.c
··· 2595 2595 } 2596 2596 trace_smb3_open_err(xid, tcon->tid, ses->Suid, 2597 2597 oparms->create_options, oparms->desired_access, rc); 2598 + if (rc == -EREMCHG) { 2599 + printk_once(KERN_WARNING "server share %s deleted\n", 2600 + tcon->treeName); 2601 + tcon->need_reconnect = true; 2602 + } 2598 2603 goto creat_exit; 2599 2604 } else 2600 2605 trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid,