Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
[firefly-linux-kernel-4.4.55.git] / fs / cifs / inode.c
index 4ff36ea8c693cd3917ac5d43e819e8c3220deb64..197cb503d5280b4a3f4425d531f444ef9b7f1baf 100644 (file)
@@ -30,6 +30,7 @@
 #include "cifsproto.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
+#include "cifs_unicode.h"
 #include "fscache.h"
 
 
@@ -546,7 +547,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
        rc = tcon->ses->server->ops->query_all_EAs(xid, tcon, path,
                        "SETFILEBITS", ea_value, 4 /* size of buf */,
                        cifs_sb->local_nls,
-                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+                       cifs_remap(cifs_sb));
        cifs_put_tlink(tlink);
        if (rc < 0)
                return (int)rc;
@@ -959,11 +960,18 @@ struct inode *cifs_root_iget(struct super_block *sb)
        struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
 
        xid = get_xid();
-       if (tcon->unix_ext)
+       if (tcon->unix_ext) {
                rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
-       else
-               rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
+               /* some servers mistakenly claim POSIX support */
+               if (rc != -EOPNOTSUPP)
+                       goto iget_no_retry;
+               cifs_dbg(VFS, "server does not support POSIX extensions");
+               tcon->unix_ext = false;
+       }
+
+       rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
 
+iget_no_retry:
        if (!inode) {
                inode = ERR_PTR(rc);
                goto out;
@@ -1124,8 +1132,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
        /* rename the file */
        rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, NULL,
                                   cifs_sb->local_nls,
-                                  cifs_sb->mnt_cifs_flags &
-                                           CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                  cifs_remap(cifs_sb));
        if (rc != 0) {
                rc = -EBUSY;
                goto undo_setattr;
@@ -1166,8 +1173,7 @@ out:
         */
 undo_rename:
        CIFSSMBRenameOpenFile(xid, tcon, fid.netfid, dentry->d_name.name,
-                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                           CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_sb->local_nls, cifs_remap(cifs_sb));
 undo_setattr:
        if (dosattr != origattr) {
                info_buf->Attributes = cpu_to_le32(origattr);
@@ -1233,7 +1239,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
                                le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                rc = CIFSPOSIXDelFile(xid, tcon, full_path,
                        SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
-                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+                       cifs_remap(cifs_sb));
                cifs_dbg(FYI, "posix del rc %d\n", rc);
                if ((rc == 0) || (rc == -ENOENT))
                        goto psx_del_no_retry;
@@ -1356,8 +1362,7 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
                }
                CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
                                       cifs_sb->local_nls,
-                                      cifs_sb->mnt_cifs_flags &
-                                      CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                      cifs_remap(cifs_sb));
        } else {
                struct TCP_Server_Info *server = tcon->ses->server;
                if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
@@ -1399,8 +1404,7 @@ cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode,
        mode &= ~current_umask();
        rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT, mode,
                             NULL /* netfid */, info, &oplock, full_path,
-                            cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                            CIFS_MOUNT_MAP_SPECIAL_CHR);
+                            cifs_sb->local_nls, cifs_remap(cifs_sb));
        if (rc == -EOPNOTSUPP)
                goto posix_mkdir_out;
        else if (rc) {
@@ -1624,8 +1628,7 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
        if (rc == 0) {
                rc = CIFSSMBRenameOpenFile(xid, tcon, fid.netfid,
                                (const char *) to_dentry->d_name.name,
-                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_sb->local_nls, cifs_remap(cifs_sb));
                CIFSSMBClose(xid, tcon, fid.netfid);
        }
 do_rename_exit:
@@ -1701,16 +1704,14 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
                tmprc = CIFSSMBUnixQPathInfo(xid, tcon, from_name,
                                             info_buf_source,
                                             cifs_sb->local_nls,
-                                            cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                            cifs_remap(cifs_sb));
                if (tmprc != 0)
                        goto unlink_target;
 
                tmprc = CIFSSMBUnixQPathInfo(xid, tcon, to_name,
                                             info_buf_target,
                                             cifs_sb->local_nls,
-                                            cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                            cifs_remap(cifs_sb));
 
                if (tmprc == 0 && (info_buf_source->UniqueId ==
                                   info_buf_target->UniqueId)) {
@@ -2075,8 +2076,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
                rc = SMBLegacyOpen(xid, tcon, full_path, FILE_OPEN,
                                   GENERIC_WRITE, CREATE_NOT_DIR, &netfid,
                                   &oplock, NULL, cifs_sb->local_nls,
-                                  cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                  cifs_remap(cifs_sb));
                if (rc == 0) {
                        unsigned int bytes_written;