diff options
Diffstat (limited to 'fs/cifs/smb2ops.c')
-rw-r--r-- | fs/cifs/smb2ops.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index f79b075f2992..6dfb865ee9d7 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -796,7 +796,6 @@ static int smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path) { - int rc; __le16 *utf16_path; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; int err_buftype = CIFS_NO_BUFFER; @@ -804,6 +803,8 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, struct kvec err_iov = {}; struct cifs_fid fid; struct cached_fid *cfid; + bool islink; + int rc, rc2; rc = open_cached_dir(xid, tcon, full_path, cifs_sb, true, &cfid); if (!rc) { @@ -833,15 +834,17 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, if (unlikely(!hdr || err_buftype == CIFS_NO_BUFFER)) goto out; - /* - * Handle weird Windows SMB server behaviour. It responds with - * STATUS_OBJECT_NAME_INVALID code to SMB2 QUERY_INFO request - * for "\<server>\<dfsname>\<linkpath>" DFS reference, - * where <dfsname> contains non-ASCII unicode symbols. - */ - if (rc != -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && - hdr->Status == STATUS_OBJECT_NAME_INVALID) - rc = -EREMOTE; + + if (rc != -EREMOTE && hdr->Status == STATUS_OBJECT_NAME_INVALID) { + rc2 = cifs_inval_name_dfs_link_error(xid, tcon, cifs_sb, + full_path, &islink); + if (rc2) { + rc = rc2; + goto out; + } + if (islink) + rc = -EREMOTE; + } if (rc == -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && cifs_sb && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)) rc = -EOPNOTSUPP; |