size_t          max_header_size;
        size_t          read_rsp_size;
        __le16          lock_cmd;
+       unsigned int    cap_unix;
+       unsigned int    cap_nt_find;
+       unsigned int    cap_large_files;
 };
 
 #define HEADER_SIZE(server) (server->vals->header_size)
        unsigned int max_vcs;   /* maximum number of smb sessions, at least
                                   those that can be specified uniquely with
                                   vcnumbers */
-       int capabilities; /* allow selective disabling of caps by smb sess */
+       unsigned int capabilities; /* selective disabling of caps by smb sess */
        int timeAdj;  /* Adjust for difference in server time zone in sec */
        __u64 CurrentMid;         /* multiplex id - rotating counter */
        char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
        __u64 Suid;             /* remote smb uid  */
        uid_t linux_uid;        /* overriding owner of files on the mount */
        uid_t cred_uid;         /* owner of credentials */
-       int capabilities;
+       unsigned int capabilities;
        char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for
                                TCP names - will ipv6 and sctp addresses fit? */
        char *user_name;        /* must not be null except during init of sess
    which do not negotiate NTLM or POSIX dialects, but instead
    negotiate one of the older LANMAN dialects */
 #define CIFS_SES_LANMAN 8
+
+static inline bool
+cap_unix(struct cifs_ses *ses)
+{
+       return ses->server->vals->cap_unix & ses->capabilities;
+}
+
 /*
  * there is one of these for each connection to a resource on a particular
  * session
 
        }
 
        /* tell server which Unix caps we support */
-       if (tcon->ses->capabilities & CAP_UNIX) {
+       if (cap_unix(tcon->ses)) {
                /* reset of caps checks mount to see if unix extensions
                   disabled for just this mount */
                reset_cifs_unix_caps(xid, tcon, cifs_sb, volume_info);
        ses->flags = 0;
        ses->capabilities = server->capabilities;
        if (linuxExtEnabled == 0)
-               ses->capabilities &= (~CAP_UNIX);
+               ses->capabilities &= (~server->vals->cap_unix);
 
        cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
                 server->sec_mode, server->capabilities, server->timeAdj);
                goto out;
        }
 
-       if (ses->capabilities & CAP_UNIX)
+       if (cap_unix(ses))
                reset_cifs_unix_caps(0, tcon, NULL, vol_info);
 out:
        kfree(vol_info->username);
 
                goto out;
        }
 
-       if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
-           !tcon->broken_posix_open &&
+       if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&
            (CIFS_UNIX_POSIX_PATH_OPS_CAP &
                        le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                rc = cifs_posix_open(full_path, &newinode,
 
                oplock = 0;
 
        if (!tcon->broken_posix_open && tcon->unix_ext &&
-           (tcon->ses->capabilities & CAP_UNIX) &&
-           (CIFS_UNIX_POSIX_PATH_OPS_CAP &
-                       le64_to_cpu(tcon->fsUnixInfo.Capability))) {
+           cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
+                               le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                /* can not refresh inode info since size could be stale */
                rc = cifs_posix_open(full_path, &inode, inode->i_sb,
                                cifs_sb->mnt_file_mode /* ignored */,
        else
                oplock = 0;
 
-       if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
+       if (tcon->unix_ext && cap_unix(tcon->ses) &&
            (CIFS_UNIX_POSIX_PATH_OPS_CAP &
-                       le64_to_cpu(tcon->fsUnixInfo.Capability))) {
-
+                               le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                /*
                 * O_CREAT, O_EXCL and O_TRUNC already had their effect on the
                 * original open. Must mask them off for a reopen.
        struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
        struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
 
-       if ((tcon->ses->capabilities & CAP_UNIX) &&
+       if (cap_unix(tcon->ses) &&
            (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
            ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
                return cifs_push_posix_locks(cfile);
        netfid = cfile->netfid;
        cinode = CIFS_I(file->f_path.dentry->d_inode);
 
-       if ((tcon->ses->capabilities & CAP_UNIX) &&
+       if (cap_unix(tcon->ses) &&
            (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
            ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
                posix_lck = true;
        unsigned int current_read_size;
        unsigned int rsize;
        struct cifs_sb_info *cifs_sb;
-       struct cifs_tcon *pTcon;
+       struct cifs_tcon *tcon;
        unsigned int xid;
        char *current_offset;
        struct cifsFileInfo *open_file;
                return rc;
        }
        open_file = file->private_data;
-       pTcon = tlink_tcon(open_file->tlink);
+       tcon = tlink_tcon(open_file->tlink);
 
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
                pid = open_file->pid;
             read_size > total_read;
             total_read += bytes_read, current_offset += bytes_read) {
                current_read_size = min_t(uint, read_size - total_read, rsize);
-
-               /* For windows me and 9x we do not want to request more
-               than it negotiated since it will refuse the read then */
-               if ((pTcon->ses) &&
-                       !(pTcon->ses->capabilities & CAP_LARGE_FILES)) {
+               /*
+                * For windows me and 9x we do not want to request more than it
+                * negotiated since it will refuse the read then.
+                */
+               if ((tcon->ses) && !(tcon->ses->capabilities &
+                               tcon->ses->server->vals->cap_large_files)) {
                        current_read_size = min_t(uint, current_read_size,
                                        CIFSMaxBufSize);
                }
                        }
                        io_parms.netfid = open_file->netfid;
                        io_parms.pid = pid;
-                       io_parms.tcon = pTcon;
+                       io_parms.tcon = tcon;
                        io_parms.offset = *poffset;
                        io_parms.length = current_read_size;
                        rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
                                return rc;
                        }
                } else {
-                       cifs_stats_bytes_read(pTcon, total_read);
+                       cifs_stats_bytes_read(tcon, total_read);
                        *poffset += bytes_read;
                }
        }
 
                goto unlink_out;
        }
 
-       if ((tcon->ses->capabilities & CAP_UNIX) &&
-               (CIFS_UNIX_POSIX_PATH_OPS_CAP &
-                       le64_to_cpu(tcon->fsUnixInfo.Capability))) {
+       if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
+                               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);
        unsigned int xid;
        struct cifs_sb_info *cifs_sb;
        struct tcon_link *tlink;
-       struct cifs_tcon *pTcon;
+       struct cifs_tcon *tcon;
        char *full_path = NULL;
        struct inode *newinode = NULL;
        struct cifs_fattr fattr;
        tlink = cifs_sb_tlink(cifs_sb);
        if (IS_ERR(tlink))
                return PTR_ERR(tlink);
-       pTcon = tlink_tcon(tlink);
+       tcon = tlink_tcon(tlink);
 
        xid = get_xid();
 
                goto mkdir_out;
        }
 
-       if ((pTcon->ses->capabilities & CAP_UNIX) &&
-               (CIFS_UNIX_POSIX_PATH_OPS_CAP &
-                       le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
+       if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP &
+                               le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                u32 oplock = 0;
                FILE_UNIX_BASIC_INFO *pInfo =
                        kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
                }
 
                mode &= ~current_umask();
-               rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
+               rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT,
                                mode, NULL /* netfid */, pInfo, &oplock,
                                full_path, cifs_sb->local_nls,
                                cifs_sb->mnt_cifs_flags &
        }
 mkdir_retry_old:
        /* BB add setting the equivalent of mode via CreateX w/ACLs */
-       rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
+       rc = CIFSSMBMkDir(xid, tcon, full_path, cifs_sb->local_nls,
                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
                cFYI(1, "cifs_mkdir returned 0x%x", rc);
                d_drop(direntry);
        } else {
 mkdir_get_info:
-               if (pTcon->unix_ext)
+               if (tcon->unix_ext)
                        rc = cifs_get_inode_info_unix(&newinode, full_path,
                                                      inode->i_sb, xid);
                else
                if (inode->i_mode & S_ISGID)
                        mode |= S_ISGID;
 
-               if (pTcon->unix_ext) {
+               if (tcon->unix_ext) {
                        struct cifs_unix_set_info_args args = {
                                .mode   = mode,
                                .ctime  = NO_CHANGE_64,
                                args.uid = NO_CHANGE_64;
                                args.gid = NO_CHANGE_64;
                        }
-                       CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
+                       CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
                                               cifs_sb->local_nls,
                                               cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                                cifsInode = CIFS_I(newinode);
                                dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
                                pInfo.Attributes = cpu_to_le32(dosattrs);
-                               tmprc = CIFSSMBSetPathInfo(xid, pTcon,
+                               tmprc = CIFSSMBSetPathInfo(xid, tcon,
                                                full_path, &pInfo,
                                                cifs_sb->local_nls,
                                                cifs_sb->mnt_cifs_flags &
 
         * but there doesn't seem to be any harm in allowing the client to
         * read them.
         */
-       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
-           && !(tcon->ses->capabilities & CAP_UNIX)) {
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) &&
+           !cap_unix(tcon->ses)) {
                rc = -EACCES;
                goto out;
        }
                                        cifs_sb->mnt_cifs_flags &
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
 
-       if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX))
+       if ((rc != 0) && cap_unix(tcon->ses))
                rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
                                             cifs_sb->local_nls);
 
 
        struct cifsFileInfo *cifsFile;
        struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
        struct tcon_link *tlink = NULL;
-       struct cifs_tcon *pTcon;
+       struct cifs_tcon *tcon;
 
        if (file->private_data == NULL) {
                tlink = cifs_sb_tlink(cifs_sb);
                }
                file->private_data = cifsFile;
                cifsFile->tlink = cifs_get_tlink(tlink);
-               pTcon = tlink_tcon(tlink);
+               tcon = tlink_tcon(tlink);
        } else {
                cifsFile = file->private_data;
-               pTcon = tlink_tcon(cifsFile->tlink);
+               tcon = tlink_tcon(cifsFile->tlink);
        }
 
        cifsFile->invalidHandle = true;
 ffirst_retry:
        /* test for Unix extensions */
        /* but now check for them on the share/mount not on the SMB session */
-/*     if (pTcon->ses->capabilities & CAP_UNIX) { */
-       if (pTcon->unix_ext)
+       /* if (cap_unix(tcon->ses) { */
+       if (tcon->unix_ext)
                cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
-       else if ((pTcon->ses->capabilities &
-                       (CAP_NT_SMBS | CAP_NT_FIND)) == 0) {
+       else if ((tcon->ses->capabilities &
+                 tcon->ses->server->vals->cap_nt_find) == 0) {
                cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
        } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
                cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
        if (backup_cred(cifs_sb))
                search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
 
-       rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls,
+       rc = CIFSFindFirst(xid, tcon, full_path, cifs_sb->local_nls,
                &cifsFile->netfid, search_flags, &cifsFile->srch_inf,
                cifs_sb->mnt_cifs_flags &
                        CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
 
        .max_header_size = MAX_CIFS_HDR_SIZE,
        .read_rsp_size = sizeof(READ_RSP),
        .lock_cmd = cpu_to_le16(SMB_COM_LOCKING_ANDX),
+       .cap_unix = CAP_UNIX,
+       .cap_nt_find = CAP_NT_SMBS | CAP_NT_FIND,
+       .cap_large_files = CAP_LARGE_FILES,
 };
 
        .header_size = sizeof(struct smb2_hdr),
        .max_header_size = MAX_SMB2_HDR_SIZE,
        .lock_cmd = SMB2_LOCK,
+       .cap_unix = 0,
+       .cap_nt_find = SMB2_NT_FIND,
+       .cap_large_files = SMB2_LARGE_FILES,
 };
 
        /* BB Do we need to validate the SecurityMode? */
        server->sec_mode = le16_to_cpu(rsp->SecurityMode);
        server->capabilities = le32_to_cpu(rsp->Capabilities);
+       /* Internal types */
+       server->capabilities |= SMB2_NT_FIND | SMB2_LARGE_FILES;
 
        security_blob = smb2_get_data_area_len(&blob_offset, &blob_length,
                                               &rsp->hdr);
 
 #define SMB2_GLOBAL_CAP_DFS            0x00000001
 #define SMB2_GLOBAL_CAP_LEASING                0x00000002 /* Resp only New to SMB2.1 */
 #define SMB2_GLOBAL_CAP_LARGE_MTU      0X00000004 /* Resp only New to SMB2.1 */
+/* Internal types */
+#define SMB2_NT_FIND                   0x00100000
+#define SMB2_LARGE_FILES               0x00200000
 
 struct smb2_negotiate_rsp {
        struct smb2_hdr hdr;