Merge tag 'v6.8-rc-part2-smb-client' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 21 Jan 2024 00:48:07 +0000 (16:48 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 21 Jan 2024 00:48:07 +0000 (16:48 -0800)
Pull smb client updates from Steve French:
 "Various smb client fixes, including multichannel and for SMB3.1.1
  POSIX extensions:

   - debugging improvement (display start time for stats)

   - two reparse point handling fixes

   - various multichannel improvements and fixes

   - SMB3.1.1 POSIX extensions open/create parsing fix

   - retry (reconnect) improvement including new retrans mount parm, and
     handling of two additional return codes that need to be retried on

   - two minor cleanup patches and another to remove duplicate query
     info code

   - two documentation cleanup, and one reviewer email correction"

* tag 'v6.8-rc-part2-smb-client' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: update iface_last_update on each query-and-update
  cifs: handle servers that still advertise multichannel after disabling
  cifs: new mount option called retrans
  cifs: reschedule periodic query for server interfaces
  smb: client: don't clobber ->i_rdev from cached reparse points
  smb: client: get rid of smb311_posix_query_path_info()
  smb: client: parse owner/group when creating reparse points
  smb: client: fix parsing of SMB3.1.1 POSIX create context
  cifs: update known bugs mentioned in kernel docs for cifs
  cifs: new nt status codes from MS-SMB2
  cifs: pick channel for tcon and tdis
  cifs: open_cached_dir should not rely on primary channel
  smb3: minor documentation updates
  Update MAINTAINERS email address
  cifs: minor comment cleanup
  smb3: show beginning time for per share stats
  cifs: remove redundant variable tcon_exist

19 files changed:
Documentation/admin-guide/cifs/todo.rst
Documentation/admin-guide/cifs/usage.rst
MAINTAINERS
fs/smb/client/cached_dir.c
fs/smb/client/cifs_debug.c
fs/smb/client/cifsfs.c
fs/smb/client/cifsglob.h
fs/smb/client/connect.c
fs/smb/client/fs_context.c
fs/smb/client/fs_context.h
fs/smb/client/inode.c
fs/smb/client/misc.c
fs/smb/client/readdir.c
fs/smb/client/smb2inode.c
fs/smb/client/smb2maperror.c
fs/smb/client/smb2ops.c
fs/smb/client/smb2pdu.c
fs/smb/client/smb2proto.h
fs/smb/client/smb2status.h

index 2646ed2e2d3e32751d3eacfc89a87b73bd2d79e4..9a65c670774ee822135c6206edd7a7c1f59c723d 100644 (file)
@@ -2,7 +2,8 @@
 TODO
 ====
 
-Version 2.14 December 21, 2018
+As of 6.7 kernel. See https://wiki.samba.org/index.php/LinuxCIFSKernel
+for list of features added by release
 
 A Partial List of Missing Features
 ==================================
@@ -12,22 +13,22 @@ for visible, important contributions to this module.  Here
 is a partial list of the known problems and missing features:
 
 a) SMB3 (and SMB3.1.1) missing optional features:
+   multichannel performance optimizations, algorithmic channel selection,
+   directory leases optimizations,
+   support for faster packet signing (GMAC),
+   support for compression over the network,
+   T10 copy offload ie "ODX" (copy chunk, and "Duplicate Extents" ioctl
+   are currently the only two server side copy mechanisms supported)
 
-   - multichannel (partially integrated), integration of multichannel with RDMA
-   - directory leases (improved metadata caching). Currently only implemented for root dir
-   - T10 copy offload ie "ODX" (copy chunk, and "Duplicate Extents" ioctl
-     currently the only two server side copy mechanisms supported)
+b) Better optimized compounding and error handling for sparse file support,
+   perhaps addition of new optional SMB3.1.1 fsctls to make collapse range
+   and insert range more atomic
 
-b) improved sparse file support (fiemap and SEEK_HOLE are implemented
-   but additional features would be supportable by the protocol such
-   as FALLOC_FL_COLLAPSE_RANGE and FALLOC_FL_INSERT_RANGE)
-
-c) Directory entry caching relies on a 1 second timer, rather than
-   using Directory Leases, currently only the root file handle is cached longer
-   by leveraging Directory Leases
+c) Support for SMB3.1.1 over QUIC (and perhaps other socket based protocols
+   like SCTP)
 
 d) quota support (needs minor kernel change since quota calls otherwise
-    won't make it to network filesystems or deviceless filesystems).
+   won't make it to network filesystems or deviceless filesystems).
 
 e) Additional use cases can be optimized to use "compounding" (e.g.
    open/query/close and open/setinfo/close) to reduce the number of
@@ -92,23 +93,20 @@ t) split cifs and smb3 support into separate modules so legacy (and less
 
 v) Additional testing of POSIX Extensions for SMB3.1.1
 
-w) Add support for additional strong encryption types, and additional spnego
-   authentication mechanisms (see MS-SMB2).  GCM-256 is now partially implemented.
+w) Support for the Mac SMB3.1.1 extensions to improve interop with Apple servers
+
+x) Support for additional authentication options (e.g. IAKERB, peer-to-peer
+   Kerberos, SCRAM and others supported by existing servers)
 
-x) Finish support for SMB3.1.1 compression
+y) Improved tracing, more eBPF trace points, better scripts for performance
+   analysis
 
 Known Bugs
 ==========
 
 See https://bugzilla.samba.org - search on product "CifsVFS" for
 current bug list.  Also check http://bugzilla.kernel.org (Product = File System, Component = CIFS)
-
-1) existing symbolic links (Windows reparse points) are recognized but
-   can not be created remotely. They are implemented for Samba and those that
-   support the CIFS Unix extensions, although earlier versions of Samba
-   overly restrict the pathnames.
-2) follow_link and readdir code does not follow dfs junctions
-   but recognizes them
+and xfstest results e.g. https://wiki.samba.org/index.php/Xfstest-results-smb3
 
 Misc testing to do
 ==================
index 5f936b4b601881d3e031b71a1cc258c5ddb9585e..aa8290a29dc88b0efdf56500ea40b1a97ddccc9c 100644 (file)
@@ -81,7 +81,7 @@ much older and less secure than the default dialect SMB3 which includes
 many advanced security features such as downgrade attack detection
 and encrypted shares and stronger signing and authentication algorithms.
 There are additional mount options that may be helpful for SMB3 to get
-improved POSIX behavior (NB: can use vers=3.0 to force only SMB3, never 2.1):
+improved POSIX behavior (NB: can use vers=3 to force SMB3 or later, never 2.1):
 
    ``mfsymlinks`` and either ``cifsacl`` or ``modefromsid`` (usually with ``idsfromsid``)
 
@@ -715,6 +715,7 @@ DebugData           Displays information about active CIFS sessions and
 Stats                  Lists summary resource usage information as well as per
                        share statistics.
 open_files             List all the open file handles on all active SMB sessions.
+mount_params            List of all mount parameters available for the module
 ======================= =======================================================
 
 Configuration pseudo-files:
@@ -864,6 +865,11 @@ i.e.::
 
     echo "value" > /sys/module/cifs/parameters/<param>
 
+More detailed descriptions of the available module parameters and their values
+can be seen by doing:
+
+    modinfo cifs (or modinfo smb3)
+
 ================= ==========================================================
 1. enable_oplocks Enable or disable oplocks. Oplocks are enabled by default.
                  [Y/y/1]. To disable use any of [N/n/0].
index 8500b857d7b54b23d31dd62375b5e43a0b9b9ea3..8d1052fa6a6924d17a4d2681fa7907c544e35186 100644 (file)
@@ -5236,7 +5236,7 @@ X:        drivers/clk/clkdev.c
 COMMON INTERNET FILE SYSTEM CLIENT (CIFS and SMB3)
 M:     Steve French <sfrench@samba.org>
 R:     Paulo Alcantara <pc@manguebit.com> (DFS, global name space)
-R:     Ronnie Sahlberg <lsahlber@redhat.com> (directory leases, sparse files)
+R:     Ronnie Sahlberg <ronniesahlberg@gmail.com> (directory leases, sparse files)
 R:     Shyam Prasad N <sprasad@microsoft.com> (multichannel)
 R:     Tom Talpey <tom@talpey.com> (RDMA, smbdirect)
 L:     linux-cifs@vger.kernel.org
index d64a306a414be0580e910842b19f150bf43863a9..971892620504730e6e2265f50c54874f3d676eac 100644 (file)
@@ -151,7 +151,7 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
                return -EOPNOTSUPP;
 
        ses = tcon->ses;
-       server = ses->server;
+       server = cifs_pick_channel(ses);
        cfids = tcon->cfids;
 
        if (!server->ops->new_lease_key)
index 60027f5aebe87f2050584994ee68699ae7ed6e5b..3e4209f41c18f854a190c523b67e3c105689ca2f 100644 (file)
@@ -659,6 +659,7 @@ static ssize_t cifs_stats_proc_write(struct file *file,
                                        spin_lock(&tcon->stat_lock);
                                        tcon->bytes_read = 0;
                                        tcon->bytes_written = 0;
+                                       tcon->stats_from_time = ktime_get_real_seconds();
                                        spin_unlock(&tcon->stat_lock);
                                        if (server->ops->clear_stats)
                                                server->ops->clear_stats(tcon);
@@ -737,8 +738,9 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
                                seq_printf(m, "\n%d) %s", i, tcon->tree_name);
                                if (tcon->need_reconnect)
                                        seq_puts(m, "\tDISCONNECTED ");
-                               seq_printf(m, "\nSMBs: %d",
-                                          atomic_read(&tcon->num_smbs_sent));
+                               seq_printf(m, "\nSMBs: %d since %ptTs UTC",
+                                          atomic_read(&tcon->num_smbs_sent),
+                                          &tcon->stats_from_time);
                                if (server->ops->print_stats)
                                        server->ops->print_stats(m, tcon);
                        }
index aa8450c9b84992c3bcf002db99b682d197aa54a5..e902de4e475af9cc3483fba922a1b11cbb068cd9 100644 (file)
@@ -681,6 +681,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
                seq_printf(s, ",rasize=%u", cifs_sb->ctx->rasize);
        if (tcon->ses->server->min_offload)
                seq_printf(s, ",esize=%u", tcon->ses->server->min_offload);
+       if (tcon->ses->server->retrans)
+               seq_printf(s, ",retrans=%u", tcon->ses->server->retrans);
        seq_printf(s, ",echo_interval=%lu",
                        tcon->ses->server->echo_interval / HZ);
 
index 879d5ef8a66eda8bd3c0aeb8dcea6556ce7acef8..20036fb16cececeaa3acffb78d81691ac86b1ec3 100644 (file)
@@ -204,6 +204,8 @@ struct cifs_open_info_data {
                };
        } reparse;
        char *symlink_target;
+       struct cifs_sid posix_owner;
+       struct cifs_sid posix_group;
        union {
                struct smb2_file_all_info fi;
                struct smb311_posix_qinfo posix_fi;
@@ -751,6 +753,7 @@ struct TCP_Server_Info {
        unsigned int    max_read;
        unsigned int    max_write;
        unsigned int    min_offload;
+       unsigned int    retrans;
        __le16  compress_algorithm;
        __u16   signing_algorithm;
        __le16  cipher_type;
@@ -1207,6 +1210,7 @@ struct cifs_tcon {
        __u64    bytes_read;
        __u64    bytes_written;
        spinlock_t stat_lock;  /* protects the two fields above */
+       time64_t stats_from_time;
        FILE_SYSTEM_DEVICE_INFO fsDevInfo;
        FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
        FILE_SYSTEM_UNIX_INFO fsUnixInfo;
index 3052a208c6ca05aa52c7e297c1c2f6eed0af7b40..bfd568f8971056b2c9ffbd509e026f140549f1af 100644 (file)
@@ -1574,6 +1574,9 @@ static int match_server(struct TCP_Server_Info *server,
        if (server->min_offload != ctx->min_offload)
                return 0;
 
+       if (server->retrans != ctx->retrans)
+               return 0;
+
        return 1;
 }
 
@@ -1798,6 +1801,7 @@ smbd_connected:
                goto out_err_crypto_release;
        }
        tcp_ses->min_offload = ctx->min_offload;
+       tcp_ses->retrans = ctx->retrans;
        /*
         * at this point we are the only ones with the pointer
         * to the struct since the kernel thread not created yet
index a3493da12ad1e6cbac7249f3e8464cf7eeff542e..52cbef2eeb28f6ba0013063b4bafcecc08c3a02d 100644 (file)
@@ -139,6 +139,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
        fsparam_u32("dir_mode", Opt_dirmode),
        fsparam_u32("port", Opt_port),
        fsparam_u32("min_enc_offload", Opt_min_enc_offload),
+       fsparam_u32("retrans", Opt_retrans),
        fsparam_u32("esize", Opt_min_enc_offload),
        fsparam_u32("bsize", Opt_blocksize),
        fsparam_u32("rasize", Opt_rasize),
@@ -1064,6 +1065,9 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
        case Opt_min_enc_offload:
                ctx->min_offload = result.uint_32;
                break;
+       case Opt_retrans:
+               ctx->retrans = result.uint_32;
+               break;
        case Opt_blocksize:
                /*
                 * inode blocksize realistically should never need to be
@@ -1619,6 +1623,8 @@ int smb3_init_fs_context(struct fs_context *fc)
        ctx->backupuid_specified = false; /* no backup intent for a user */
        ctx->backupgid_specified = false; /* no backup intent for a group */
 
+       ctx->retrans = 1;
+
 /*
  *     short int override_uid = -1;
  *     short int override_gid = -1;
index cf46916286d029a9bd36ea4980786456bd11449f..182ce11cbe9362eccf73eebadcdcfc2ee7ac7988 100644 (file)
@@ -118,6 +118,7 @@ enum cifs_param {
        Opt_file_mode,
        Opt_dirmode,
        Opt_min_enc_offload,
+       Opt_retrans,
        Opt_blocksize,
        Opt_rasize,
        Opt_rsize,
@@ -245,6 +246,7 @@ struct smb3_fs_context {
        unsigned int rsize;
        unsigned int wsize;
        unsigned int min_offload;
+       unsigned int retrans;
        bool sockopt_tcp_nodelay:1;
        /* attribute cache timemout for files and directories in jiffies */
        unsigned long acregmax;
index 9f37c1758f732cb310a0dc958b288b225e851412..f0989484f2c648796d923fcd3f998b150b1f92cf 100644 (file)
@@ -665,8 +665,6 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
 /* Fill a cifs_fattr struct with info from POSIX info struct */
 static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr,
                                       struct cifs_open_info_data *data,
-                                      struct cifs_sid *owner,
-                                      struct cifs_sid *group,
                                       struct super_block *sb)
 {
        struct smb311_posix_qinfo *info = &data->posix_fi;
@@ -722,8 +720,8 @@ out_reparse:
                fattr->cf_symlink_target = data->symlink_target;
                data->symlink_target = NULL;
        }
-       sid_to_id(cifs_sb, owner, fattr, SIDOWNER);
-       sid_to_id(cifs_sb, group, fattr, SIDGROUP);
+       sid_to_id(cifs_sb, &data->posix_owner, fattr, SIDOWNER);
+       sid_to_id(cifs_sb, &data->posix_group, fattr, SIDGROUP);
 
        cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n",
                fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
@@ -1070,9 +1068,7 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
                                 const unsigned int xid,
                                 struct cifs_tcon *tcon,
                                 const char *full_path,
-                                struct cifs_fattr *fattr,
-                                struct cifs_sid *owner,
-                                struct cifs_sid *group)
+                                struct cifs_fattr *fattr)
 {
        struct TCP_Server_Info *server = tcon->ses->server;
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
@@ -1117,7 +1113,7 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
        }
 
        if (tcon->posix_extensions)
-               smb311_posix_info_to_fattr(fattr, data, owner, group, sb);
+               smb311_posix_info_to_fattr(fattr, data, sb);
        else
                cifs_open_info_to_fattr(fattr, data, sb);
 out:
@@ -1171,8 +1167,7 @@ static int cifs_get_fattr(struct cifs_open_info_data *data,
                 */
                if (cifs_open_data_reparse(data)) {
                        rc = reparse_info_to_fattr(data, sb, xid, tcon,
-                                                  full_path, fattr,
-                                                  NULL, NULL);
+                                                  full_path, fattr);
                } else {
                        cifs_open_info_to_fattr(fattr, data, sb);
                }
@@ -1317,10 +1312,10 @@ static int smb311_posix_get_fattr(struct cifs_open_info_data *data,
                                  const unsigned int xid)
 {
        struct cifs_open_info_data tmp_data = {};
+       struct TCP_Server_Info *server;
        struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
        struct cifs_tcon *tcon;
        struct tcon_link *tlink;
-       struct cifs_sid owner, group;
        int tmprc;
        int rc = 0;
 
@@ -1328,14 +1323,14 @@ static int smb311_posix_get_fattr(struct cifs_open_info_data *data,
        if (IS_ERR(tlink))
                return PTR_ERR(tlink);
        tcon = tlink_tcon(tlink);
+       server = tcon->ses->server;
 
        /*
         * 1. Fetch file metadata if not provided (data)
         */
        if (!data) {
-               rc = smb311_posix_query_path_info(xid, tcon, cifs_sb,
-                                                 full_path, &tmp_data,
-                                                 &owner, &group);
+               rc = server->ops->query_path_info(xid, tcon, cifs_sb,
+                                                 full_path, &tmp_data);
                data = &tmp_data;
        }
 
@@ -1347,11 +1342,9 @@ static int smb311_posix_get_fattr(struct cifs_open_info_data *data,
        case 0:
                if (cifs_open_data_reparse(data)) {
                        rc = reparse_info_to_fattr(data, sb, xid, tcon,
-                                                  full_path, fattr,
-                                                  &owner, &group);
+                                                  full_path, fattr);
                } else {
-                       smb311_posix_info_to_fattr(fattr, data,
-                                                  &owner, &group, sb);
+                       smb311_posix_info_to_fattr(fattr, data, sb);
                }
                break;
        case -EREMOTE:
index c2137ea3c2538937665056619d3ad17a0089eb29..0748d7b757b95a88abcab10418d5f4d8dc78642d 100644 (file)
@@ -140,6 +140,7 @@ tcon_info_alloc(bool dir_leases_enabled)
        spin_lock_init(&ret_buf->stat_lock);
        atomic_set(&ret_buf->num_local_opens, 0);
        atomic_set(&ret_buf->num_remote_opens, 0);
+       ret_buf->stats_from_time = ktime_get_real_seconds();
 #ifdef CONFIG_CIFS_DFS_UPCALL
        INIT_LIST_HEAD(&ret_buf->dfs_ses_list);
 #endif
index 056cae1ddccef274010b09e64ddbe5231a485f40..94255401b38dcb24c705f255731db2791e171c8d 100644 (file)
@@ -133,14 +133,14 @@ retry:
                                 * Query dir responses don't provide enough
                                 * information about reparse points other than
                                 * their reparse tags.  Save an invalidation by
-                                * not clobbering the existing mode, size and
-                                * symlink target (if any) when reparse tag and
-                                * ctime haven't changed.
+                                * not clobbering some existing attributes when
+                                * reparse tag and ctime haven't changed.
                                 */
                                rc = 0;
                                if (fattr->cf_cifsattrs & ATTR_REPARSE) {
                                        if (likely(reparse_inode_match(inode, fattr))) {
                                                fattr->cf_mode = inode->i_mode;
+                                               fattr->cf_rdev = inode->i_rdev;
                                                fattr->cf_eof = CIFS_I(inode)->server_eof;
                                                fattr->cf_symlink_target = NULL;
                                        } else {
@@ -645,10 +645,10 @@ static int cifs_entry_is_dot(struct cifs_dirent *de, bool is_unicode)
 static int is_dir_changed(struct file *file)
 {
        struct inode *inode = file_inode(file);
-       struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
+       struct cifsInodeInfo *cifs_inode_info = CIFS_I(inode);
 
-       if (cifsInfo->time == 0)
-               return 1; /* directory was changed, perhaps due to unlink */
+       if (cifs_inode_info->time == 0)
+               return 1; /* directory was changed, e.g. unlink or new file */
        else
                return 0;
 
index 5053a5550abeda064234e82c037fbbd89df6f746..a652200540c8aa5d2aa0ecd68ed50cc66f587d05 100644 (file)
@@ -56,6 +56,35 @@ static inline __u32 file_create_options(struct dentry *dentry)
        return 0;
 }
 
+/* Parse owner and group from SMB3.1.1 POSIX query info */
+static int parse_posix_sids(struct cifs_open_info_data *data,
+                           struct kvec *rsp_iov)
+{
+       struct smb2_query_info_rsp *qi = rsp_iov->iov_base;
+       unsigned int out_len = le32_to_cpu(qi->OutputBufferLength);
+       unsigned int qi_len = sizeof(data->posix_fi);
+       int owner_len, group_len;
+       u8 *sidsbuf, *sidsbuf_end;
+
+       if (out_len <= qi_len)
+               return -EINVAL;
+
+       sidsbuf = (u8 *)qi + le16_to_cpu(qi->OutputBufferOffset) + qi_len;
+       sidsbuf_end = sidsbuf + out_len - qi_len;
+
+       owner_len = posix_info_sid_size(sidsbuf, sidsbuf_end);
+       if (owner_len == -1)
+               return -EINVAL;
+
+       memcpy(&data->posix_owner, sidsbuf, owner_len);
+       group_len = posix_info_sid_size(sidsbuf + owner_len, sidsbuf_end);
+       if (group_len == -1)
+               return -EINVAL;
+
+       memcpy(&data->posix_group, sidsbuf + owner_len, group_len);
+       return 0;
+}
+
 /*
  * note: If cfile is passed, the reference to it is dropped here.
  * So make sure that you do not reuse cfile after return from this func.
@@ -69,7 +98,6 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
                            __u32 desired_access, __u32 create_disposition,
                            __u32 create_options, umode_t mode, struct kvec *in_iov,
                            int *cmds, int num_cmds, struct cifsFileInfo *cfile,
-                           __u8 **extbuf, size_t *extbuflen,
                            struct kvec *out_iov, int *out_buftype)
 {
 
@@ -494,21 +522,9 @@ finished:
                                        &rsp_iov[i + 1], sizeof(idata->posix_fi) /* add SIDs */,
                                        (char *)&idata->posix_fi);
                        }
-                       if (rc == 0) {
-                               unsigned int length = le32_to_cpu(qi_rsp->OutputBufferLength);
-
-                               if (length > sizeof(idata->posix_fi)) {
-                                       char *base = (char *)rsp_iov[i + 1].iov_base +
-                                               le16_to_cpu(qi_rsp->OutputBufferOffset) +
-                                               sizeof(idata->posix_fi);
-                                       *extbuflen = length - sizeof(idata->posix_fi);
-                                       *extbuf = kmemdup(base, *extbuflen, GFP_KERNEL);
-                                       if (!*extbuf)
-                                               rc = -ENOMEM;
-                               } else {
-                                       rc = -EINVAL;
-                               }
-                       }
+                       if (rc == 0)
+                               rc = parse_posix_sids(idata, &rsp_iov[i + 1]);
+
                        SMB2_query_info_free(&rqst[num_rqst++]);
                        if (rc)
                                trace_smb3_posix_query_info_compound_err(xid,  ses->Suid,
@@ -662,7 +678,7 @@ int smb2_query_path_info(const unsigned int xid,
        struct smb2_hdr *hdr;
        struct kvec in_iov[2], out_iov[3] = {};
        int out_buftype[3] = {};
-       int cmds[2] = { SMB2_OP_QUERY_INFO,  };
+       int cmds[2];
        bool islink;
        int i, num_cmds;
        int rc, rc2;
@@ -670,20 +686,36 @@ int smb2_query_path_info(const unsigned int xid,
        data->adjust_tz = false;
        data->reparse_point = false;
 
-       if (strcmp(full_path, ""))
-               rc = -ENOENT;
-       else
-               rc = open_cached_dir(xid, tcon, full_path, cifs_sb, false, &cfid);
-       /* If it is a root and its handle is cached then use it */
-       if (!rc) {
-               if (cfid->file_all_info_is_valid) {
-                       memcpy(&data->fi, &cfid->file_all_info, sizeof(data->fi));
+       /*
+        * BB TODO: Add support for using cached root handle in SMB3.1.1 POSIX.
+        * Create SMB2_query_posix_info worker function to do non-compounded
+        * query when we already have an open file handle for this. For now this
+        * is fast enough (always using the compounded version).
+        */
+       if (!tcon->posix_extensions) {
+               if (*full_path) {
+                       rc = -ENOENT;
                } else {
-                       rc = SMB2_query_info(xid, tcon, cfid->fid.persistent_fid,
-                                            cfid->fid.volatile_fid, &data->fi);
+                       rc = open_cached_dir(xid, tcon, full_path,
+                                            cifs_sb, false, &cfid);
+               }
+               /* If it is a root and its handle is cached then use it */
+               if (!rc) {
+                       if (cfid->file_all_info_is_valid) {
+                               memcpy(&data->fi, &cfid->file_all_info,
+                                      sizeof(data->fi));
+                       } else {
+                               rc = SMB2_query_info(xid, tcon,
+                                                    cfid->fid.persistent_fid,
+                                                    cfid->fid.volatile_fid,
+                                                    &data->fi);
+                       }
+                       close_cached_dir(cfid);
+                       return rc;
                }
-               close_cached_dir(cfid);
-               return rc;
+               cmds[0] = SMB2_OP_QUERY_INFO;
+       } else {
+               cmds[0] = SMB2_OP_POSIX_QUERY_INFO;
        }
 
        in_iov[0].iov_base = data;
@@ -693,9 +725,8 @@ int smb2_query_path_info(const unsigned int xid,
        cifs_get_readable_path(tcon, full_path, &cfile);
        rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
                              FILE_READ_ATTRIBUTES, FILE_OPEN,
-                             create_options, ACL_NO_MODE,
-                             in_iov, cmds, 1, cfile,
-                             NULL, NULL, out_iov, out_buftype);
+                             create_options, ACL_NO_MODE, in_iov,
+                             cmds, 1, cfile, out_iov, out_buftype);
        hdr = out_iov[0].iov_base;
        /*
         * If first iov is unset, then SMB session was dropped or we've got a
@@ -707,6 +738,10 @@ int smb2_query_path_info(const unsigned int xid,
        switch (rc) {
        case 0:
        case -EOPNOTSUPP:
+               /*
+                * BB TODO: When support for special files added to Samba
+                * re-verify this path.
+                */
                rc = parse_create_response(data, cifs_sb, &out_iov[0]);
                if (rc || !data->reparse_point)
                        goto out;
@@ -722,8 +757,8 @@ int smb2_query_path_info(const unsigned int xid,
                cifs_get_readable_path(tcon, full_path, &cfile);
                rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
                                      FILE_READ_ATTRIBUTES, FILE_OPEN,
-                                     create_options, ACL_NO_MODE, in_iov, cmds,
-                                     num_cmds, cfile, NULL, NULL, NULL, NULL);
+                                     create_options, ACL_NO_MODE, in_iov,
+                                     cmds, num_cmds, cfile, NULL, NULL);
                break;
        case -EREMOTE:
                break;
@@ -746,101 +781,6 @@ out:
        return rc;
 }
 
-int smb311_posix_query_path_info(const unsigned int xid,
-                                struct cifs_tcon *tcon,
-                                struct cifs_sb_info *cifs_sb,
-                                const char *full_path,
-                                struct cifs_open_info_data *data,
-                                struct cifs_sid *owner,
-                                struct cifs_sid *group)
-{
-       int rc;
-       __u32 create_options = 0;
-       struct cifsFileInfo *cfile;
-       struct kvec in_iov[2], out_iov[3] = {};
-       int out_buftype[3] = {};
-       __u8 *sidsbuf = NULL;
-       __u8 *sidsbuf_end = NULL;
-       size_t sidsbuflen = 0;
-       size_t owner_len, group_len;
-       int cmds[2] = { SMB2_OP_POSIX_QUERY_INFO,  };
-       int i, num_cmds;
-
-       data->adjust_tz = false;
-       data->reparse_point = false;
-
-       /*
-        * BB TODO: Add support for using the cached root handle.
-        * Create SMB2_query_posix_info worker function to do non-compounded query
-        * when we already have an open file handle for this. For now this is fast enough
-        * (always using the compounded version).
-        */
-       in_iov[0].iov_base = data;
-       in_iov[0].iov_len = sizeof(*data);
-       in_iov[1] = in_iov[0];
-
-       cifs_get_readable_path(tcon, full_path, &cfile);
-       rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
-                             FILE_READ_ATTRIBUTES, FILE_OPEN,
-                             create_options, ACL_NO_MODE, in_iov, cmds, 1,
-                             cfile, &sidsbuf, &sidsbuflen, out_iov, out_buftype);
-       /*
-        * If first iov is unset, then SMB session was dropped or we've got a
-        * cached open file (@cfile).
-        */
-       if (!out_iov[0].iov_base || out_buftype[0] == CIFS_NO_BUFFER)
-               goto out;
-
-       switch (rc) {
-       case 0:
-       case -EOPNOTSUPP:
-               /* BB TODO: When support for special files added to Samba re-verify this path */
-               rc = parse_create_response(data, cifs_sb, &out_iov[0]);
-               if (rc || !data->reparse_point)
-                       goto out;
-
-               if (data->reparse.tag == IO_REPARSE_TAG_SYMLINK) {
-                       /* symlink already parsed in create response */
-                       num_cmds = 1;
-               } else {
-                       cmds[1] = SMB2_OP_GET_REPARSE;
-                       num_cmds = 2;
-               }
-               create_options |= OPEN_REPARSE_POINT;
-               cifs_get_readable_path(tcon, full_path, &cfile);
-               rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
-                                     FILE_READ_ATTRIBUTES, FILE_OPEN,
-                                     create_options, ACL_NO_MODE, in_iov, cmds,
-                                     num_cmds, cfile, &sidsbuf, &sidsbuflen, NULL, NULL);
-               break;
-       }
-
-out:
-       if (rc == 0) {
-               sidsbuf_end = sidsbuf + sidsbuflen;
-
-               owner_len = posix_info_sid_size(sidsbuf, sidsbuf_end);
-               if (owner_len == -1) {
-                       rc = -EINVAL;
-                       goto out;
-               }
-               memcpy(owner, sidsbuf, owner_len);
-
-               group_len = posix_info_sid_size(
-                       sidsbuf + owner_len, sidsbuf_end);
-               if (group_len == -1) {
-                       rc = -EINVAL;
-                       goto out;
-               }
-               memcpy(group, sidsbuf + owner_len, group_len);
-       }
-
-       kfree(sidsbuf);
-       for (i = 0; i < ARRAY_SIZE(out_buftype); i++)
-               free_rsp_buf(out_buftype[i], out_iov[i].iov_base);
-       return rc;
-}
-
 int
 smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
           struct cifs_tcon *tcon, const char *name,
@@ -848,9 +788,9 @@ smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
 {
        return smb2_compound_op(xid, tcon, cifs_sb, name,
                                FILE_WRITE_ATTRIBUTES, FILE_CREATE,
-                               CREATE_NOT_FILE, mode, NULL,
-                               &(int){SMB2_OP_MKDIR}, 1,
-                               NULL, NULL, NULL, NULL, NULL);
+                               CREATE_NOT_FILE, mode,
+                               NULL, &(int){SMB2_OP_MKDIR}, 1,
+                               NULL, NULL, NULL);
 }
 
 void
@@ -875,7 +815,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
                                 FILE_WRITE_ATTRIBUTES, FILE_CREATE,
                                 CREATE_NOT_FILE, ACL_NO_MODE, &in_iov,
                                 &(int){SMB2_OP_SET_INFO}, 1,
-                                cfile, NULL, NULL, NULL, NULL);
+                                cfile, NULL, NULL);
        if (tmprc == 0)
                cifs_i->cifsAttrs = dosattrs;
 }
@@ -887,8 +827,9 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
        drop_cached_dir_by_name(xid, tcon, name, cifs_sb);
        return smb2_compound_op(xid, tcon, cifs_sb, name,
                                DELETE, FILE_OPEN, CREATE_NOT_FILE,
-                               ACL_NO_MODE, NULL, &(int){SMB2_OP_RMDIR}, 1,
-                               NULL, NULL, NULL, NULL, NULL);
+                               ACL_NO_MODE, NULL,
+                               &(int){SMB2_OP_RMDIR}, 1,
+                               NULL, NULL, NULL);
 }
 
 int
@@ -897,8 +838,9 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
 {
        return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
                                CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT,
-                               ACL_NO_MODE, NULL, &(int){SMB2_OP_DELETE}, 1,
-                               NULL, NULL, NULL, NULL, NULL);
+                               ACL_NO_MODE, NULL,
+                               &(int){SMB2_OP_DELETE}, 1,
+                               NULL, NULL, NULL);
 }
 
 static int smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
@@ -919,8 +861,8 @@ static int smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
        in_iov.iov_base = smb2_to_name;
        in_iov.iov_len = 2 * UniStrnlen((wchar_t *)smb2_to_name, PATH_MAX);
        rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access,
-                             FILE_OPEN, create_options, ACL_NO_MODE, &in_iov,
-                             &command, 1, cfile, NULL, NULL, NULL, NULL);
+                             FILE_OPEN, create_options, ACL_NO_MODE,
+                             &in_iov, &command, 1, cfile, NULL, NULL);
 smb2_rename_path:
        kfree(smb2_to_name);
        return rc;
@@ -971,7 +913,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
                                FILE_WRITE_DATA, FILE_OPEN,
                                0, ACL_NO_MODE, &in_iov,
                                &(int){SMB2_OP_SET_EOF}, 1,
-                               cfile, NULL, NULL, NULL, NULL);
+                               cfile, NULL, NULL);
 }
 
 int
@@ -999,8 +941,8 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
        rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
                              FILE_WRITE_ATTRIBUTES, FILE_OPEN,
                              0, ACL_NO_MODE, &in_iov,
-                             &(int){SMB2_OP_SET_INFO}, 1, cfile,
-                             NULL, NULL, NULL, NULL);
+                             &(int){SMB2_OP_SET_INFO}, 1,
+                             cfile, NULL, NULL);
        cifs_put_tlink(tlink);
        return rc;
 }
@@ -1035,7 +977,7 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
                cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
                rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
                                      da, cd, co, ACL_NO_MODE, in_iov,
-                                     cmds, 2, cfile, NULL, NULL, NULL, NULL);
+                                     cmds, 2, cfile, NULL, NULL);
                if (!rc) {
                        rc = smb311_posix_get_inode_info(&new, full_path,
                                                         data, sb, xid);
@@ -1045,7 +987,7 @@ struct inode *smb2_get_reparse_inode(struct cifs_open_info_data *data,
                cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile);
                rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
                                      da, cd, co, ACL_NO_MODE, in_iov,
-                                     cmds, 2, cfile, NULL, NULL, NULL, NULL);
+                                     cmds, 2, cfile, NULL, NULL);
                if (!rc) {
                        rc = cifs_get_inode_info(&new, full_path,
                                                 data, sb, xid, NULL);
@@ -1072,8 +1014,8 @@ int smb2_query_reparse_point(const unsigned int xid,
        rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
                              FILE_READ_ATTRIBUTES, FILE_OPEN,
                              OPEN_REPARSE_POINT, ACL_NO_MODE, &in_iov,
-                             &(int){SMB2_OP_GET_REPARSE}, 1, cfile,
-                             NULL, NULL, NULL, NULL);
+                             &(int){SMB2_OP_GET_REPARSE}, 1,
+                             cfile, NULL, NULL);
        if (rc)
                goto out;
 
index 1a90dd78b238f0de191421bd0d1838164bff9778..ac1895358908abff42e51059644aed30be670373 100644 (file)
@@ -1210,6 +1210,8 @@ static const struct status_to_posix_error smb2_error_map_table[] = {
        {STATUS_INVALID_TASK_INDEX, -EIO, "STATUS_INVALID_TASK_INDEX"},
        {STATUS_THREAD_ALREADY_IN_TASK, -EIO, "STATUS_THREAD_ALREADY_IN_TASK"},
        {STATUS_CALLBACK_BYPASS, -EIO, "STATUS_CALLBACK_BYPASS"},
+       {STATUS_SERVER_UNAVAILABLE, -EAGAIN, "STATUS_SERVER_UNAVAILABLE"},
+       {STATUS_FILE_NOT_AVAILABLE, -EAGAIN, "STATUS_FILE_NOT_AVAILABLE"},
        {STATUS_PORT_CLOSED, -EIO, "STATUS_PORT_CLOSED"},
        {STATUS_MESSAGE_LOST, -EIO, "STATUS_MESSAGE_LOST"},
        {STATUS_INVALID_MESSAGE, -EIO, "STATUS_INVALID_MESSAGE"},
index 01a5bd7e6a307f1d20619001e2a1e5da7f8e2e87..d9553c2556a290dcea14434e00df9d854e713aa3 100644 (file)
@@ -614,7 +614,8 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
                                 "multichannel not available\n"
                                 "Empty network interface list returned by server %s\n",
                                 ses->server->hostname);
-               rc = -EINVAL;
+               rc = -EOPNOTSUPP;
+               ses->iface_last_update = jiffies;
                goto out;
        }
 
@@ -712,7 +713,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
 
                ses->iface_count++;
                spin_unlock(&ses->iface_lock);
-               ses->iface_last_update = jiffies;
 next_iface:
                nb_iface++;
                next = le32_to_cpu(p->Next);
@@ -734,11 +734,7 @@ next_iface:
        if ((bytes_left > 8) || p->Next)
                cifs_dbg(VFS, "%s: incomplete interface info\n", __func__);
 
-
-       if (!ses->iface_count) {
-               rc = -EINVAL;
-               goto out;
-       }
+       ses->iface_last_update = jiffies;
 
 out:
        /*
index bd25c34dc398b6460c37e3c1ea778fdc0cca6b80..288199f0b987df98ba3fab9320523bc16e73092d 100644 (file)
@@ -156,6 +156,57 @@ out:
        return;
 }
 
+/* helper function for code reuse */
+static int
+cifs_chan_skip_or_disable(struct cifs_ses *ses,
+                         struct TCP_Server_Info *server,
+                         bool from_reconnect)
+{
+       struct TCP_Server_Info *pserver;
+       unsigned int chan_index;
+
+       if (SERVER_IS_CHAN(server)) {
+               cifs_dbg(VFS,
+                       "server %s does not support multichannel anymore. Skip secondary channel\n",
+                        ses->server->hostname);
+
+               spin_lock(&ses->chan_lock);
+               chan_index = cifs_ses_get_chan_index(ses, server);
+               if (chan_index == CIFS_INVAL_CHAN_INDEX) {
+                       spin_unlock(&ses->chan_lock);
+                       goto skip_terminate;
+               }
+
+               ses->chans[chan_index].server = NULL;
+               spin_unlock(&ses->chan_lock);
+
+               /*
+                * the above reference of server by channel
+                * needs to be dropped without holding chan_lock
+                * as cifs_put_tcp_session takes a higher lock
+                * i.e. cifs_tcp_ses_lock
+                */
+               cifs_put_tcp_session(server, from_reconnect);
+
+               server->terminate = true;
+               cifs_signal_cifsd_for_reconnect(server, false);
+
+               /* mark primary server as needing reconnect */
+               pserver = server->primary_server;
+               cifs_signal_cifsd_for_reconnect(pserver, false);
+skip_terminate:
+               mutex_unlock(&ses->session_mutex);
+               return -EHOSTDOWN;
+       }
+
+       cifs_server_dbg(VFS,
+               "server does not support multichannel anymore. Disable all other channels\n");
+       cifs_disable_secondary_channels(ses);
+
+
+       return 0;
+}
+
 static int
 smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
               struct TCP_Server_Info *server, bool from_reconnect)
@@ -164,8 +215,6 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
        struct nls_table *nls_codepage = NULL;
        struct cifs_ses *ses;
        int xid;
-       struct TCP_Server_Info *pserver;
-       unsigned int chan_index;
 
        /*
         * SMB2s NegProt, SessSetup, Logoff do not have tcon yet so
@@ -310,44 +359,11 @@ again:
                 */
                if (ses->chan_count > 1 &&
                    !(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
-                       if (SERVER_IS_CHAN(server)) {
-                               cifs_dbg(VFS, "server %s does not support " \
-                                        "multichannel anymore. skipping secondary channel\n",
-                                        ses->server->hostname);
-
-                               spin_lock(&ses->chan_lock);
-                               chan_index = cifs_ses_get_chan_index(ses, server);
-                               if (chan_index == CIFS_INVAL_CHAN_INDEX) {
-                                       spin_unlock(&ses->chan_lock);
-                                       goto skip_terminate;
-                               }
-
-                               ses->chans[chan_index].server = NULL;
-                               spin_unlock(&ses->chan_lock);
-
-                               /*
-                                * the above reference of server by channel
-                                * needs to be dropped without holding chan_lock
-                                * as cifs_put_tcp_session takes a higher lock
-                                * i.e. cifs_tcp_ses_lock
-                                */
-                               cifs_put_tcp_session(server, from_reconnect);
-
-                               server->terminate = true;
-                               cifs_signal_cifsd_for_reconnect(server, false);
-
-                               /* mark primary server as needing reconnect */
-                               pserver = server->primary_server;
-                               cifs_signal_cifsd_for_reconnect(pserver, false);
-
-skip_terminate:
+                       rc = cifs_chan_skip_or_disable(ses, server,
+                                                      from_reconnect);
+                       if (rc) {
                                mutex_unlock(&ses->session_mutex);
-                               rc = -EHOSTDOWN;
                                goto out;
-                       } else {
-                               cifs_server_dbg(VFS, "does not support " \
-                                        "multichannel anymore. disabling all other channels\n");
-                               cifs_disable_secondary_channels(ses);
                        }
                }
 
@@ -395,20 +411,35 @@ skip_sess_setup:
                rc = SMB3_request_interfaces(xid, tcon, false);
                free_xid(xid);
 
-               if (rc)
+               if (rc == -EOPNOTSUPP) {
+                       /*
+                        * some servers like Azure SMB server do not advertise
+                        * that multichannel has been disabled with server
+                        * capabilities, rather return STATUS_NOT_IMPLEMENTED.
+                        * treat this as server not supporting multichannel
+                        */
+
+                       rc = cifs_chan_skip_or_disable(ses, server,
+                                                      from_reconnect);
+                       goto skip_add_channels;
+               } else if (rc)
                        cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n",
                                 __func__, rc);
 
                if (ses->chan_max > ses->chan_count &&
+                   ses->iface_count &&
                    !SERVER_IS_CHAN(server)) {
                        if (ses->chan_count == 1)
                                cifs_server_dbg(VFS, "supports multichannel now\n");
 
                        cifs_try_adding_channels(ses);
+                       queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
+                                          (SMB_INTERFACE_POLL_INTERVAL * HZ));
                }
        } else {
                mutex_unlock(&ses->session_mutex);
        }
+skip_add_channels:
 
        if (smb2_command != SMB2_INTERNAL_CMD)
                mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
@@ -1958,10 +1989,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
        __le16 *unc_path = NULL;
        int flags = 0;
        unsigned int total_len;
-       struct TCP_Server_Info *server;
-
-       /* always use master channel */
-       server = ses->server;
+       struct TCP_Server_Info *server = cifs_pick_channel(ses);
 
        cifs_dbg(FYI, "TCON\n");
 
@@ -2094,6 +2122,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
        struct smb2_tree_disconnect_req *req; /* response is trivial */
        int rc = 0;
        struct cifs_ses *ses = tcon->ses;
+       struct TCP_Server_Info *server = cifs_pick_channel(ses);
        int flags = 0;
        unsigned int total_len;
        struct kvec iov[1];
@@ -2116,7 +2145,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
 
        invalidate_all_cached_dirs(tcon);
 
-       rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, ses->server,
+       rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, server,
                                 (void **) &req,
                                 &total_len);
        if (rc)
@@ -2134,7 +2163,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
        rqst.rq_iov = iov;
        rqst.rq_nvec = 1;
 
-       rc = cifs_send_recv(xid, ses, ses->server,
+       rc = cifs_send_recv(xid, ses, server,
                            &rqst, &resp_buf_type, flags, &rsp_iov);
        cifs_small_buf_release(req);
        if (rc) {
@@ -2279,7 +2308,7 @@ int smb2_parse_contexts(struct TCP_Server_Info *server,
 
                noff = le16_to_cpu(cc->NameOffset);
                nlen = le16_to_cpu(cc->NameLength);
-               if (noff + nlen >= doff)
+               if (noff + nlen > doff)
                        return -EINVAL;
 
                name = (char *)cc + noff;
@@ -3918,7 +3947,7 @@ void smb2_reconnect_server(struct work_struct *work)
        struct cifs_ses *ses, *ses2;
        struct cifs_tcon *tcon, *tcon2;
        struct list_head tmp_list, tmp_ses_list;
-       bool tcon_exist = false, ses_exist = false;
+       bool ses_exist = false;
        bool tcon_selected = false;
        int rc;
        bool resched = false;
@@ -3964,7 +3993,7 @@ void smb2_reconnect_server(struct work_struct *work)
                        if (tcon->need_reconnect || tcon->need_reopen_files) {
                                tcon->tc_count++;
                                list_add_tail(&tcon->rlist, &tmp_list);
-                               tcon_selected = tcon_exist = true;
+                               tcon_selected = true;
                        }
                }
                /*
@@ -3973,7 +4002,7 @@ void smb2_reconnect_server(struct work_struct *work)
                 */
                if (ses->tcon_ipc && ses->tcon_ipc->need_reconnect) {
                        list_add_tail(&ses->tcon_ipc->rlist, &tmp_list);
-                       tcon_selected = tcon_exist = true;
+                       tcon_selected = true;
                        cifs_smb_ses_inc_refcount(ses);
                }
                /*
index 343ada691e763bfce3eb64f1c7871922f7eb7a76..0034b537b0b3f9dd057ce5183f05b6fedb147f77 100644 (file)
@@ -299,9 +299,7 @@ int smb311_posix_query_path_info(const unsigned int xid,
                                 struct cifs_tcon *tcon,
                                 struct cifs_sb_info *cifs_sb,
                                 const char *full_path,
-                                struct cifs_open_info_data *data,
-                                struct cifs_sid *owner,
-                                struct cifs_sid *group);
+                                struct cifs_open_info_data *data);
 int posix_info_parse(const void *beg, const void *end,
                     struct smb2_posix_info_parsed *out);
 int posix_info_sid_size(const void *beg, const void *end);
index a9e958166fc53a3c4b5d7a23efb8d326deec3543..9c6d79b0bd4978cea9e33bcfd17432219a9a5232 100644 (file)
@@ -982,6 +982,8 @@ struct ntstatus {
 #define STATUS_INVALID_TASK_INDEX cpu_to_le32(0xC0000501)
 #define STATUS_THREAD_ALREADY_IN_TASK cpu_to_le32(0xC0000502)
 #define STATUS_CALLBACK_BYPASS cpu_to_le32(0xC0000503)
+#define STATUS_SERVER_UNAVAILABLE cpu_to_le32(0xC0000466)
+#define STATUS_FILE_NOT_AVAILABLE cpu_to_le32(0xC0000467)
 #define STATUS_PORT_CLOSED cpu_to_le32(0xC0000700)
 #define STATUS_MESSAGE_LOST cpu_to_le32(0xC0000701)
 #define STATUS_INVALID_MESSAGE cpu_to_le32(0xC0000702)