Remap reserved posix characters by default (part 3/3)
authorSteve French <smfrench@gmail.com>
Sat, 27 Sep 2014 07:19:01 +0000 (02:19 -0500)
committerSteve French <smfrench@gmail.com>
Thu, 16 Oct 2014 20:20:20 +0000 (15:20 -0500)
This is a bigger patch, but its size is mostly due to
a single change for how we check for remapping illegal characters
in file names - a lot of repeated, small changes to
the way callers request converting file names.

The final patch in the series does the following:

1) changes default behavior for cifs to be more intuitive.
Currently we do not map by default to seven reserved characters,
ie those valid in POSIX but not in NTFS/CIFS/SMB3/Windows,
unless a mount option (mapchars) is specified.  Change this
to by default always map and map using the SFM maping
(like the Mac uses) unless the server negotiates the CIFS Unix
Extensions (like Samba does when mounting with the cifs protocol)
when the remapping of the characters is unnecessary.  This should
help SMB3 mounts in particular since Samba will likely be
able to implement this mapping with its new "vfs_fruit" module
as it will be doing for the Mac.
2) if the user specifies the existing "mapchars" mount option then
use the "SFU" (Microsoft Services for Unix, SUA) style mapping of
the seven characters instead.
3) if the user specifies "nomapposix" then disable SFM/MAC style mapping
(so no character remapping would be used unless the user specifies
"mapchars" on mount as well, as above).
4) change all the places in the code that check for the superblock
flag on the mount which is set by mapchars and passed in on all
path based operation and change it to use a small function call
instead to set the mapping type properly (and check for the
mapping type in the cifs unicode functions)

Signed-off-by: Steve French <smfrench@gmail.com>
fs/cifs/cifs_unicode.c
fs/cifs/cifs_unicode.h
fs/cifs/cifsglob.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/readdir.c
fs/cifs/smb1ops.c
fs/cifs/smbencrypt.c
fs/cifs/xattr.c

index 0aa2c5c2cfe2165dd94ccb6ae885f241490a29b3..0303c6793d903ab07cb7d1829bc372f0be3fc15f 100644 (file)
@@ -20,6 +20,7 @@
  */
 #include <linux/fs.h>
 #include <linux/slab.h>
+#include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
 #include "cifs_uniupr.h"
 #include "cifspdu.h"
@@ -61,6 +62,20 @@ cifs_utf16_bytes(const __le16 *from, int maxbytes,
        return outlen;
 }
 
+int cifs_remap(struct cifs_sb_info *cifs_sb)
+{
+       int map_type;
+
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
+               map_type = SFM_MAP_UNI_RSVD;
+       else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
+               map_type = SFU_MAP_UNI_RSVD;
+       else
+               map_type = NO_MAP_UNI_RSVD;
+
+       return map_type;
+}
+
 /* Convert character using the SFU - "Services for Unix" remapping range */
 static bool
 convert_sfu_char(const __u16 src_char, char *target)
index 30af32b55a940fe34afdba19bdfa4a1af66cdd35..bdc52cb9a676db0a9041d7e198810ce8df2aca9a 100644 (file)
@@ -112,6 +112,7 @@ char *cifs_strndup_from_utf16(const char *src, const int maxlen,
                              const struct nls_table *codepage);
 extern int cifsConvertToUTF16(__le16 *target, const char *source, int maxlen,
                              const struct nls_table *cp, int mapChars);
+extern int cifs_remap(struct cifs_sb_info *cifs_sb);
 #ifdef CONFIG_CIFS_SMB2
 extern __le16 *cifs_strndup_to_utf16(const char *src, const int maxlen,
                                     int *utf16_len, const struct nls_table *cp,
index dae7e3709cc6051a72974c5f0c7d0a80dc94d42a..02a33e5299042079a6121a638d034c1139d88677 100644 (file)
@@ -466,6 +466,7 @@ struct smb_vol {
        bool direct_io:1;
        bool strict_io:1; /* strict cache behavior */
        bool remap:1;      /* set to remap seven reserved chars in filenames */
+       bool sfu_remap:1;  /* remap seven reserved chars ala SFU */
        bool posix_paths:1; /* unset to not ask for posix pathnames. */
        bool no_linux_ext:1;
        bool sfu_emul:1;
@@ -499,6 +500,7 @@ struct smb_vol {
 #define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
                         CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
                         CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
+                        CIFS_MOUNT_MAP_SFM_CHR | \
                         CIFS_MOUNT_UNX_EMUL | CIFS_MOUNT_NO_BRL | \
                         CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_OVERR_UID | \
                         CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
index 66f65001a6d836513b5872ba24b273b82464a67e..61d00a6e398fe5ed30160e2eba02df49876281ed 100644 (file)
@@ -867,7 +867,7 @@ CIFSSMBDelFile(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
        int rc = 0;
        int bytes_returned;
        int name_len;
-       int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
+       int remap = cifs_remap(cifs_sb);
 
 DelFileRetry:
        rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
@@ -913,7 +913,7 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
        int rc = 0;
        int bytes_returned;
        int name_len;
-       int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
+       int remap = cifs_remap(cifs_sb);
 
        cifs_dbg(FYI, "In CIFSSMBRmDir\n");
 RmDirRetry:
@@ -958,7 +958,7 @@ CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
        CREATE_DIRECTORY_RSP *pSMBr = NULL;
        int bytes_returned;
        int name_len;
-       int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
+       int remap = cifs_remap(cifs_sb);
 
        cifs_dbg(FYI, "In CIFSSMBMkDir\n");
 MkDirRetry:
@@ -1280,7 +1280,7 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
        __u16 count;
        struct cifs_sb_info *cifs_sb = oparms->cifs_sb;
        struct cifs_tcon *tcon = oparms->tcon;
-       int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
+       int remap = cifs_remap(cifs_sb);
        const struct nls_table *nls = cifs_sb->local_nls;
        int create_options = oparms->create_options;
        int desired_access = oparms->desired_access;
@@ -2572,7 +2572,7 @@ CIFSSMBRename(const unsigned int xid, struct cifs_tcon *tcon,
        int bytes_returned;
        int name_len, name_len2;
        __u16 count;
-       int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
+       int remap = cifs_remap(cifs_sb);
 
        cifs_dbg(FYI, "In CIFSSMBRename\n");
 renameRetry:
@@ -2968,7 +2968,7 @@ CIFSCreateHardLink(const unsigned int xid, struct cifs_tcon *tcon,
        int bytes_returned;
        int name_len, name_len2;
        __u16 count;
-       int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
+       int remap = cifs_remap(cifs_sb);
 
        cifs_dbg(FYI, "In CIFSCreateHardLink\n");
 winCreateHardLinkRetry:
@@ -4367,7 +4367,7 @@ findFirstRetry:
                return rc;
 
        nls_codepage = cifs_sb->local_nls;
-       remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
+       remap = cifs_remap(cifs_sb);
 
        if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
                name_len =
@@ -5527,7 +5527,7 @@ CIFSSMBSetEOF(const unsigned int xid, struct cifs_tcon *tcon,
        int name_len;
        int rc = 0;
        int bytes_returned = 0;
-       int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
+       int remap = cifs_remap(cifs_sb);
 
        __u16 params, byte_count, data_count, param_offset, offset;
 
index d8eb6a74b21178c43cb82ee49211e818bed84d2a..24fa08d261fbc352cd89239cf0184de2ba1ce3d2 100644 (file)
@@ -70,6 +70,7 @@ enum {
        Opt_forcegid, Opt_noforcegid,
        Opt_noblocksend, Opt_noautotune,
        Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
+       Opt_mapposix, Opt_nomapposix,
        Opt_mapchars, Opt_nomapchars, Opt_sfu,
        Opt_nosfu, Opt_nodfs, Opt_posixpaths,
        Opt_noposixpaths, Opt_nounix,
@@ -124,8 +125,10 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_soft, "soft" },
        { Opt_perm, "perm" },
        { Opt_noperm, "noperm" },
-       { Opt_mapchars, "mapchars" },
+       { Opt_mapchars, "mapchars" }, /* SFU style */
        { Opt_nomapchars, "nomapchars" },
+       { Opt_mapposix, "mapposix" }, /* SFM style */
+       { Opt_nomapposix, "nomapposix" },
        { Opt_sfu, "sfu" },
        { Opt_nosfu, "nosfu" },
        { Opt_nodfs, "nodfs" },
@@ -1231,6 +1234,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
        vol->linux_uid = current_uid();
        vol->linux_gid = current_gid();
 
+       /*
+        * default to SFM style remapping of seven reserved characters
+        * unless user overrides it or we negotiate CIFS POSIX where
+        * it is unnecessary.  Can not simultaneously use more than one mapping
+        * since then readdir could list files that open could not open
+        */
+       vol->remap = true;
+
        /* default to only allowing write access to owner of the mount */
        vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
 
@@ -1338,10 +1349,18 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        vol->noperm = 1;
                        break;
                case Opt_mapchars:
-                       vol->remap = 1;
+                       vol->sfu_remap = true;
+                       vol->remap = false; /* disable SFM mapping */
                        break;
                case Opt_nomapchars:
-                       vol->remap = 0;
+                       vol->sfu_remap = false;
+                       break;
+               case Opt_mapposix:
+                       vol->remap = true;
+                       vol->sfu_remap = false; /* disable SFU mapping */
+                       break;
+               case Opt_nomapposix:
+                       vol->remap = false;
                        break;
                case Opt_sfu:
                        vol->sfu_emul = 1;
@@ -3197,6 +3216,8 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
        if (pvolume_info->server_ino)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
        if (pvolume_info->remap)
+               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR;
+       if (pvolume_info->sfu_remap)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
        if (pvolume_info->no_xattr)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
@@ -3340,8 +3361,7 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
        ref_path = check_prefix ? full_path + 1 : volume_info->UNC + 1;
 
        rc = get_dfs_path(xid, ses, ref_path, cifs_sb->local_nls,
-                         &num_referrals, &referrals,
-                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+                         &num_referrals, &referrals, cifs_remap(cifs_sb));
 
        if (!rc && num_referrals > 0) {
                char *fake_devname = NULL;
index 4ff36ea8c693cd3917ac5d43e819e8c3220deb64..c23bdec805c557748d3f205704638bd889c2afa7 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;
@@ -1124,8 +1125,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 +1166,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 +1232,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 +1355,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 +1397,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 +1621,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 +1697,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 +2069,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;
 
index ce7d4bbf3120a343b8b91e8fc57c68b587b57402..190bf0eb71b092c9006d02434eb3de931df6a5b0 100644 (file)
@@ -28,6 +28,7 @@
 #include "cifsproto.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
+#include "cifs_unicode.h"
 #ifdef CONFIG_CIFS_SMB2
 #include "smb2proto.h"
 #endif
@@ -566,8 +567,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
        if (tcon->unix_ext)
                rc = CIFSUnixCreateHardLink(xid, tcon, from_name, to_name,
                                            cifs_sb->local_nls,
-                                           cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                           cifs_remap(cifs_sb));
        else {
                server = tcon->ses->server;
                if (!server->ops->create_hardlink) {
index 5bf3d0a746f890e884537f41481e0e541879b92c..8fd2a95860ba9874f1bc2d008f9272d3f5825b2a 100644 (file)
@@ -239,7 +239,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
        rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,
                        OPEN_REPARSE_POINT, &fid, &oplock, NULL,
                        cifs_sb->local_nls,
-                       cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+                       cifs_remap(cifs_sb);
        if (!rc) {
                tmpbuffer = kmalloc(maxpath);
                rc = CIFSSMBQueryReparseLinkInfo(xid, ptcon, full_path,
@@ -706,13 +706,7 @@ static int cifs_filldir(char *find_entry, struct file *file,
                struct nls_table *nlt = cifs_sb->local_nls;
                int map_type;
 
-               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR)
-                       map_type = SFM_MAP_UNI_RSVD;
-               else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
-                       map_type = SFU_MAP_UNI_RSVD;
-               else
-                       map_type = NO_MAP_UNI_RSVD;
-
+               map_type = cifs_remap(cifs_sb);
                name.name = scratch_buf;
                name.len =
                        cifs_from_utf16((char *)name.name, (__le16 *)de.name,
index 2aca620193cd2e7bab6f8abbeac25fa46db4484e..d2979036a4c72756e91f9fa6c454337585c06800 100644 (file)
@@ -23,6 +23,7 @@
 #include "cifsproto.h"
 #include "cifs_debug.h"
 #include "cifspdu.h"
+#include "cifs_unicode.h"
 
 /*
  * An NT cancel request header looks just like the original request except:
@@ -530,13 +531,11 @@ cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
 
        rc = CIFSSMBQPathInfo(xid, tcon, full_path, file_info,
                              0 /* not legacy */, cifs_sb->local_nls,
-                             cifs_sb->mnt_cifs_flags &
-                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                             cifs_remap(cifs_sb));
 
        if (rc == -EOPNOTSUPP || rc == -EINVAL)
                rc = SMBQueryInformation(xid, tcon, full_path, file_info,
-                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_sb->local_nls, cifs_remap(cifs_sb));
        kfree(file_info);
        return rc;
 }
@@ -552,8 +551,7 @@ cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
 
        /* could do find first instead but this returns more info */
        rc = CIFSSMBQPathInfo(xid, tcon, full_path, data, 0 /* not legacy */,
-                             cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                             cifs_sb->local_nls, cifs_remap(cifs_sb));
        /*
         * BB optimize code so we do not make the above call when server claims
         * no NT SMB support and the above call failed at least once - set flag
@@ -562,8 +560,7 @@ cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
        if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
                rc = SMBQueryInformation(xid, tcon, full_path, data,
                                         cifs_sb->local_nls,
-                                        cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                        cifs_remap(cifs_sb));
                *adjustTZ = true;
        }
 
@@ -611,8 +608,7 @@ cifs_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
         */
        return CIFSGetSrvInodeNumber(xid, tcon, full_path, uniqueid,
                                     cifs_sb->local_nls,
-                                    cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                    cifs_remap(cifs_sb));
 }
 
 static int
@@ -703,8 +699,7 @@ cifs_mkdir_setinfo(struct inode *inode, const char *full_path,
        dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
        info.Attributes = cpu_to_le32(dosattrs);
        rc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls,
-                               cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_remap(cifs_sb));
        if (rc == 0)
                cifsInode->cifsAttrs = dosattrs;
 }
@@ -720,8 +715,7 @@ cifs_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
                                     oparms->create_options,
                                     &oparms->fid->netfid, oplock, buf,
                                     oparms->cifs_sb->local_nls,
-                                    oparms->cifs_sb->mnt_cifs_flags
-                                               & CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                    cifs_remap(oparms->cifs_sb));
        return CIFS_open(xid, oparms, oplock, buf);
 }
 
@@ -800,8 +794,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,
        tcon = tlink_tcon(tlink);
 
        rc = CIFSSMBSetPathInfo(xid, tcon, full_path, buf, cifs_sb->local_nls,
-                                       cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_remap(cifs_sb));
        if (rc == 0) {
                cinode->cifsAttrs = le32_to_cpu(buf->Attributes);
                goto out;
index 43eb1367b10353ae1e71a5196b83587df6939160..6c1566366a6613cbc494fe46344c8fd00342a82b 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/random.h>
+#include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
 #include "cifspdu.h"
 #include "cifsglob.h"
index 5ac836a86b1885d4e1766e831a1b56d3a263e277..72a4d10653d6e746919bae66d9fe46316cdaa812 100644 (file)
@@ -28,6 +28,8 @@
 #include "cifsglob.h"
 #include "cifsproto.h"
 #include "cifs_debug.h"
+#include "cifs_fs_sb.h"
+#include "cifs_unicode.h"
 
 #define MAX_EA_VALUE_SIZE 65535
 #define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
@@ -85,8 +87,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
                if (pTcon->ses->server->ops->set_EA)
                        rc = pTcon->ses->server->ops->set_EA(xid, pTcon,
                                full_path, ea_name, NULL, (__u16)0,
-                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_sb->local_nls, cifs_remap(cifs_sb));
        }
 remove_ea_exit:
        kfree(full_path);
@@ -154,8 +155,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                if (pTcon->ses->server->ops->set_EA)
                        rc = pTcon->ses->server->ops->set_EA(xid, pTcon,
                                full_path, ea_name, ea_value, (__u16)value_size,
-                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_sb->local_nls, cifs_remap(cifs_sb));
        } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)
                   == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
@@ -165,8 +165,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                if (pTcon->ses->server->ops->set_EA)
                        rc = pTcon->ses->server->ops->set_EA(xid, pTcon,
                                full_path, ea_name, ea_value, (__u16)value_size,
-                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_sb->local_nls, cifs_remap(cifs_sb));
        } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
                        strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
 #ifdef CONFIG_CIFS_ACL
@@ -199,8 +198,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                                rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
                                        ea_value, (const int)value_size,
                                        ACL_TYPE_ACCESS, cifs_sb->local_nls,
-                                       cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                       cifs_remap(cifs_sb));
                        cifs_dbg(FYI, "set POSIX ACL rc %d\n", rc);
 #else
                        cifs_dbg(FYI, "set POSIX ACL not supported\n");
@@ -212,8 +210,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
                                rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
                                        ea_value, (const int)value_size,
                                        ACL_TYPE_DEFAULT, cifs_sb->local_nls,
-                                       cifs_sb->mnt_cifs_flags &
-                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
+                                       cifs_remap(cifs_sb));
                        cifs_dbg(FYI, "set POSIX default ACL rc %d\n", rc);
 #else
                        cifs_dbg(FYI, "set default POSIX ACL not supported\n");
@@ -285,8 +282,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                if (pTcon->ses->server->ops->query_all_EAs)
                        rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
                                full_path, ea_name, ea_value, buf_size,
-                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_sb->local_nls, cifs_remap(cifs_sb));
        } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                        goto get_ea_exit;
@@ -295,8 +291,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                if (pTcon->ses->server->ops->query_all_EAs)
                        rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
                                full_path, ea_name, ea_value, buf_size,
-                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_sb->local_nls, cifs_remap(cifs_sb));
        } else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
                          strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
 #ifdef CONFIG_CIFS_POSIX
@@ -304,8 +299,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                        rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
                                ea_value, buf_size, ACL_TYPE_ACCESS,
                                cifs_sb->local_nls,
-                               cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_remap(cifs_sb));
 #else
                cifs_dbg(FYI, "Query POSIX ACL not supported yet\n");
 #endif /* CONFIG_CIFS_POSIX */
@@ -316,8 +310,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
                        rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
                                ea_value, buf_size, ACL_TYPE_DEFAULT,
                                cifs_sb->local_nls,
-                               cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_remap(cifs_sb));
 #else
                cifs_dbg(FYI, "Query POSIX default ACL not supported yet\n");
 #endif /* CONFIG_CIFS_POSIX */
@@ -421,8 +414,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
        if (pTcon->ses->server->ops->query_all_EAs)
                rc = pTcon->ses->server->ops->query_all_EAs(xid, pTcon,
                                full_path, NULL, data, buf_size,
-                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
-                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
+                               cifs_sb->local_nls, cifs_remap(cifs_sb));
 list_ea_exit:
        kfree(full_path);
        free_xid(xid);