]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
cifs: Add a tracepoint to log EIO errors
authorDavid Howells <dhowells@redhat.com>
Fri, 24 Oct 2025 08:25:31 +0000 (09:25 +0100)
committerSteve French <stfrench@microsoft.com>
Fri, 5 Dec 2025 23:11:43 +0000 (17:11 -0600)
Add a tracepoint to log EIO errors and give it the capacity to convey up to
two integers of information.  This is then wrapped with three functions:

 int smb_EIO(enum smb_eio_trace trace)
 int smb_EIO1(enum smb_eio_trace trace, unsigned long info)
 int smb_EIO2(enum smb_eio_trace trace, unsigned long info,
      unsigned long info2)

depending on how many bits of info are desired to be logged with any
particular trace.  The functions all return -EIO and can be used in place
of -EIO.

The trace argument is an enum value that gets translated to a string when
the trace is printed.

This makes is easier to log EIO instances when the client is under high
load than turning on a printk wrapper such as cifs_dbg().  Granted, EIO
could have its own separate EIO printing since EIO shouldn't happen.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
27 files changed:
fs/smb/client/cached_dir.c
fs/smb/client/cifsacl.c
fs/smb/client/cifsencrypt.c
fs/smb/client/cifsglob.h
fs/smb/client/cifsproto.h
fs/smb/client/cifssmb.c
fs/smb/client/cifstransport.c
fs/smb/client/compress.c
fs/smb/client/connect.c
fs/smb/client/dir.c
fs/smb/client/file.c
fs/smb/client/inode.c
fs/smb/client/link.c
fs/smb/client/misc.c
fs/smb/client/netmisc.c
fs/smb/client/readdir.c
fs/smb/client/reparse.c
fs/smb/client/sess.c
fs/smb/client/smb2file.c
fs/smb/client/smb2inode.c
fs/smb/client/smb2maperror.c
fs/smb/client/smb2ops.c
fs/smb/client/smb2pdu.c
fs/smb/client/smb2transport.c
fs/smb/client/trace.h
fs/smb/client/transport.c
fs/smb/client/xattr.c

index e3ea6fe7edb474ea18763311b9520cd1df755351..1db7ab6c2529ce1f26746f4b77d2d564bcc3efa5 100644 (file)
@@ -176,7 +176,7 @@ replay_again:
        server = cifs_pick_channel(ses);
 
        if (!server->ops->new_lease_key)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_no_lease_key);
 
        utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
        if (!utf16_path)
index ce2ebc213a1d91a5939f3e7ee32c087140d89828..7e6e473bd4a029d3b2efa9ad2ff7978353a36e83 100644 (file)
@@ -300,7 +300,7 @@ id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
                         __func__, sidtype == SIDOWNER ? 'u' : 'g', cid);
                goto out_revert_creds;
        } else if (sidkey->datalen < CIFS_SID_BASE_SIZE) {
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_malformed_sid_key, sidkey->datalen);
                cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu)\n",
                         __func__, sidkey->datalen);
                goto invalidate_key;
@@ -317,7 +317,8 @@ id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid)
 
        ksid_size = CIFS_SID_BASE_SIZE + (ksid->num_subauth * sizeof(__le32));
        if (ksid_size > sidkey->datalen) {
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_malformed_ksid_key,
+                             ksid_size, sidkey->datalen);
                cifs_dbg(FYI, "%s: Downcall contained malformed key (datalen=%hu, ksid_size=%u)\n",
                         __func__, sidkey->datalen, ksid_size);
                goto invalidate_key;
@@ -352,7 +353,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid,
        if (unlikely(psid->num_subauth > SID_MAX_SUB_AUTHORITIES)) {
                cifs_dbg(FYI, "%s: %u subauthorities is too many!\n",
                         __func__, psid->num_subauth);
-               return -EIO;
+               return smb_EIO2(smb_eio_trace_sid_too_many_auth,
+                               psid->num_subauth, SID_MAX_SUB_AUTHORITIES);
        }
 
        if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) ||
@@ -1227,7 +1229,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
        __u32 dacloffset;
 
        if (pntsd == NULL)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        owner_sid_ptr = (struct smb_sid *)((char *)pntsd +
                                le32_to_cpu(pntsd->osidoffset));
index a9a57904c6b1852a6bf839a1dfdec714d4a99701..ca2a84e8673ee573eb324f50156874b880abdff0 100644 (file)
@@ -75,11 +75,13 @@ static int cifs_sig_iter(const struct iov_iter *iter, size_t maxsize,
                         struct cifs_calc_sig_ctx *ctx)
 {
        struct iov_iter tmp_iter = *iter;
-       int err = -EIO;
+       size_t did;
+       int err;
 
-       if (iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err,
-                                      cifs_sig_step) != maxsize)
-               return err;
+       did = iterate_and_advance_kernel(&tmp_iter, maxsize, ctx, &err,
+                                        cifs_sig_step);
+       if (did != maxsize)
+               return smb_EIO2(smb_eio_trace_sig_iter, did, maxsize);
        return 0;
 }
 
@@ -96,7 +98,8 @@ int __cifs_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server,
        iov_iter_kvec(&iter, ITER_SOURCE, rqst->rq_iov, rqst->rq_nvec, size);
 
        if (iov_iter_count(&iter) <= 4)
-               return -EIO;
+               return smb_EIO2(smb_eio_trace_sig_data_too_small,
+                               iov_iter_count(&iter), 4);
 
        rc = cifs_sig_iter(&iter, iov_iter_count(&iter), ctx);
        if (rc < 0)
index 1f93c309dfe8968137c6141bfd19fc68b2af0081..a8cfe9b87a20d25938ce8309e1ac5e53056740a7 100644 (file)
@@ -2206,94 +2206,6 @@ static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const
        dst->FileNameLength = src->FileNameLength;
 }
 
-static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
-                                  int num_rqst,
-                                  const u8 *sig)
-{
-       unsigned int len, skip;
-       unsigned int nents = 0;
-       unsigned long addr;
-       size_t data_size;
-       int i, j;
-
-       /*
-        * The first rqst has a transform header where the first 20 bytes are
-        * not part of the encrypted blob.
-        */
-       skip = 20;
-
-       /* Assumes the first rqst has a transform header as the first iov.
-        * I.e.
-        * rqst[0].rq_iov[0]  is transform header
-        * rqst[0].rq_iov[1+] data to be encrypted/decrypted
-        * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
-        */
-       for (i = 0; i < num_rqst; i++) {
-               data_size = iov_iter_count(&rqst[i].rq_iter);
-
-               /* We really don't want a mixture of pinned and unpinned pages
-                * in the sglist.  It's hard to keep track of which is what.
-                * Instead, we convert to a BVEC-type iterator higher up.
-                */
-               if (data_size &&
-                   WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter)))
-                       return -EIO;
-
-               /* We also don't want to have any extra refs or pins to clean
-                * up in the sglist.
-                */
-               if (data_size &&
-                   WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter)))
-                       return -EIO;
-
-               for (j = 0; j < rqst[i].rq_nvec; j++) {
-                       struct kvec *iov = &rqst[i].rq_iov[j];
-
-                       addr = (unsigned long)iov->iov_base + skip;
-                       if (is_vmalloc_or_module_addr((void *)addr)) {
-                               len = iov->iov_len - skip;
-                               nents += DIV_ROUND_UP(offset_in_page(addr) + len,
-                                                     PAGE_SIZE);
-                       } else {
-                               nents++;
-                       }
-                       skip = 0;
-               }
-               if (data_size)
-                       nents += iov_iter_npages(&rqst[i].rq_iter, INT_MAX);
-       }
-       nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
-       return nents;
-}
-
-/* We can not use the normal sg_set_buf() as we will sometimes pass a
- * stack object as buf.
- */
-static inline void cifs_sg_set_buf(struct sg_table *sgtable,
-                                  const void *buf,
-                                  unsigned int buflen)
-{
-       unsigned long addr = (unsigned long)buf;
-       unsigned int off = offset_in_page(addr);
-
-       addr &= PAGE_MASK;
-       if (is_vmalloc_or_module_addr((void *)addr)) {
-               do {
-                       unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
-
-                       sg_set_page(&sgtable->sgl[sgtable->nents++],
-                                   vmalloc_to_page((void *)addr), len, off);
-
-                       off = 0;
-                       addr += PAGE_SIZE;
-                       buflen -= len;
-               } while (buflen);
-       } else {
-               sg_set_page(&sgtable->sgl[sgtable->nents++],
-                           virt_to_page((void *)addr), buflen, off);
-       }
-}
-
 #define CIFS_OPARMS(_cifs_sb, _tcon, _path, _da, _cd, _co, _mode) \
        ((struct cifs_open_parms) { \
                .tcon = _tcon, \
index d72d66dcb953223ea1e63b904d4c59eb4e7dd4e3..5d54de12f0f409756fdf1afdc665c4db47e1e1e5 100644 (file)
@@ -786,4 +786,110 @@ static inline void cifs_free_open_info(struct cifs_open_info_data *data)
        memset(data, 0, sizeof(*data));
 }
 
+static inline int smb_EIO(enum smb_eio_trace trace)
+{
+       trace_smb3_eio(trace, 0, 0);
+       return -EIO;
+}
+
+static inline int smb_EIO1(enum smb_eio_trace trace, unsigned long info)
+{
+       trace_smb3_eio(trace, info, 0);
+       return -EIO;
+}
+
+static inline int smb_EIO2(enum smb_eio_trace trace, unsigned long info, unsigned long info2)
+{
+       trace_smb3_eio(trace, info, info2);
+       return -EIO;
+}
+
+static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
+                                  int num_rqst,
+                                  const u8 *sig)
+{
+       unsigned int len, skip;
+       unsigned int nents = 0;
+       unsigned long addr;
+       size_t data_size;
+       int i, j;
+
+       /*
+        * The first rqst has a transform header where the first 20 bytes are
+        * not part of the encrypted blob.
+        */
+       skip = 20;
+
+       /* Assumes the first rqst has a transform header as the first iov.
+        * I.e.
+        * rqst[0].rq_iov[0]  is transform header
+        * rqst[0].rq_iov[1+] data to be encrypted/decrypted
+        * rqst[1+].rq_iov[0+] data to be encrypted/decrypted
+        */
+       for (i = 0; i < num_rqst; i++) {
+               data_size = iov_iter_count(&rqst[i].rq_iter);
+
+               /* We really don't want a mixture of pinned and unpinned pages
+                * in the sglist.  It's hard to keep track of which is what.
+                * Instead, we convert to a BVEC-type iterator higher up.
+                */
+               if (data_size &&
+                   WARN_ON_ONCE(user_backed_iter(&rqst[i].rq_iter)))
+                       return smb_EIO(smb_eio_trace_user_iter);
+
+               /* We also don't want to have any extra refs or pins to clean
+                * up in the sglist.
+                */
+               if (data_size &&
+                   WARN_ON_ONCE(iov_iter_extract_will_pin(&rqst[i].rq_iter)))
+                       return smb_EIO(smb_eio_trace_extract_will_pin);
+
+               for (j = 0; j < rqst[i].rq_nvec; j++) {
+                       struct kvec *iov = &rqst[i].rq_iov[j];
+
+                       addr = (unsigned long)iov->iov_base + skip;
+                       if (is_vmalloc_or_module_addr((void *)addr)) {
+                               len = iov->iov_len - skip;
+                               nents += DIV_ROUND_UP(offset_in_page(addr) + len,
+                                                     PAGE_SIZE);
+                       } else {
+                               nents++;
+                       }
+                       skip = 0;
+               }
+               if (data_size)
+                       nents += iov_iter_npages(&rqst[i].rq_iter, INT_MAX);
+       }
+       nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
+       return nents;
+}
+
+/* We can not use the normal sg_set_buf() as we will sometimes pass a
+ * stack object as buf.
+ */
+static inline void cifs_sg_set_buf(struct sg_table *sgtable,
+                                  const void *buf,
+                                  unsigned int buflen)
+{
+       unsigned long addr = (unsigned long)buf;
+       unsigned int off = offset_in_page(addr);
+
+       addr &= PAGE_MASK;
+       if (is_vmalloc_or_module_addr((void *)addr)) {
+               do {
+                       unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
+
+                       sg_set_page(&sgtable->sgl[sgtable->nents++],
+                                   vmalloc_to_page((void *)addr), len, off);
+
+                       off = 0;
+                       addr += PAGE_SIZE;
+                       buflen -= len;
+               } while (buflen);
+       } else {
+               sg_set_page(&sgtable->sgl[sgtable->nents++],
+                           virt_to_page((void *)addr), buflen, off);
+       }
+}
+
 #endif                 /* _CIFSPROTO_H */
index a6a9a74d59cb7407d971ff98b0211e29b8256697..3db1a892c526d6801befa58a21ef55c468dd2361 100644 (file)
@@ -373,7 +373,8 @@ decode_ext_sec_blob(struct cifs_ses *ses, SMB_NEGOTIATE_RSP *pSMBr)
 
        count = get_bcc(&pSMBr->hdr);
        if (count < SMB1_CLIENT_GUID_SIZE)
-               return -EIO;
+               return smb_EIO2(smb_eio_trace_neg_sec_blob_too_small,
+                               count, SMB1_CLIENT_GUID_SIZE);
 
        spin_lock(&cifs_tcp_ses_lock);
        if (server->srv_count > 1) {
@@ -432,7 +433,7 @@ CIFSSMBNegotiate(const unsigned int xid,
 
        if (!server) {
                WARN(1, "%s: server is NULL!\n", __func__);
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
        }
 
        rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
@@ -516,7 +517,8 @@ CIFSSMBNegotiate(const unsigned int xid,
                server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
                rc = decode_ext_sec_blob(ses, pSMBr);
        } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
-               rc = -EIO; /* no crypt key only if plain text pwd */
+               /* no crypt key only if plain text pwd */
+               rc = smb_EIO(smb_eio_trace_neg_no_crypt_key);
        } else {
                server->negflavor = CIFS_NEGFLAVOR_UNENCAP;
                server->capabilities &= ~CAP_EXTENDED_SECURITY;
@@ -542,7 +544,7 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
 
        /* BB: do we need to check this? These should never be NULL. */
        if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        /*
         * No need to return error on this operation if tid invalidated and
@@ -553,7 +555,7 @@ CIFSSMBTDis(const unsigned int xid, struct cifs_tcon *tcon)
        spin_lock(&tcon->ses->chan_lock);
        if ((tcon->need_reconnect) || CIFS_ALL_CHANS_NEED_RECONNECT(tcon->ses)) {
                spin_unlock(&tcon->ses->chan_lock);
-               return -EIO;
+               return smb_EIO(smb_eio_trace_tdis_in_reconnect);
        }
        spin_unlock(&tcon->ses->chan_lock);
 
@@ -650,7 +652,7 @@ CIFSSMBLogoff(const unsigned int xid, struct cifs_ses *ses)
         * should probably be a BUG()
         */
        if (!ses || !ses->server)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        mutex_lock(&ses->session_mutex);
        spin_lock(&ses->chan_lock);
@@ -980,7 +982,8 @@ PsxCreat:
        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
        if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
-               rc = -EIO;      /* bad smb */
+               rc = smb_EIO2(smb_eio_trace_create_rsp_too_small,
+                             get_bcc(&pSMBr->hdr), sizeof(OPEN_PSX_RSP));
                goto psx_create_err;
        }
 
@@ -1371,11 +1374,12 @@ do_retry:
                break;
        case MID_RESPONSE_MALFORMED:
                trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed);
-               rdata->result = -EIO;
+               rdata->result = smb_EIO(smb_eio_trace_read_rsp_malformed);
                break;
        default:
                trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown);
-               rdata->result = -EIO;
+               rdata->result = smb_EIO1(smb_eio_trace_read_mid_state_unknown,
+                                        mid->mid_state);
                break;
        }
 
@@ -1446,7 +1450,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
                wct = 10; /* old style read */
                if ((rdata->subreq.start >> 32) > 0)  {
                        /* can not handle this big offset for old */
-                       return -EIO;
+                       return smb_EIO(smb_eio_trace_read_too_far);
                }
        }
 
@@ -1521,7 +1525,7 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
                wct = 10; /* old style read */
                if ((offset >> 32) > 0)  {
                        /* can not handle this big offset for old */
-                       return -EIO;
+                       return smb_EIO(smb_eio_trace_read_too_far);
                }
        }
 
@@ -1576,7 +1580,8 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
                                || (data_length > count)) {
                        cifs_dbg(FYI, "bad length %d for count %d\n",
                                 data_length, count);
-                       rc = -EIO;
+                       rc = smb_EIO2(smb_eio_trace_read_overlarge,
+                                     data_length, count);
                        *nbytes = 0;
                } else {
                        pReadData = (char *) (&pSMBr->hdr.Protocol) +
@@ -1635,7 +1640,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
                wct = 12;
                if ((offset >> 32) > 0) {
                        /* can not handle big offset for old srv */
-                       return -EIO;
+                       return smb_EIO(smb_eio_trace_write_too_far);
                }
        }
 
@@ -1786,11 +1791,12 @@ cifs_writev_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid)
                break;
        case MID_RESPONSE_MALFORMED:
                trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed);
-               result = -EIO;
+               result = smb_EIO(smb_eio_trace_write_rsp_malformed);
                break;
        default:
                trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown);
-               result = -EIO;
+               result = smb_EIO1(smb_eio_trace_write_mid_state_unknown,
+                                 mid->mid_state);
                break;
        }
 
@@ -1825,7 +1831,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
                wct = 12;
                if (wdata->subreq.start >> 32 > 0) {
                        /* can not handle big offset for old srv */
-                       rc = -EIO;
+                       rc = smb_EIO(smb_eio_trace_write_too_far);
                        goto out;
                }
        }
@@ -1917,7 +1923,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
                wct = 12;
                if ((offset >> 32) > 0) {
                        /* can not handle big offset for old srv */
-                       return -EIO;
+                       return smb_EIO(smb_eio_trace_write_too_far);
                }
        }
        rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
@@ -1973,7 +1979,7 @@ CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
                cifs_dbg(FYI, "Send error Write2 = %d\n", rc);
        } else if (resp_buf_type == 0) {
                /* presumably this can not happen, but best to be safe */
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_write_bad_buf_type, resp_buf_type);
        } else {
                WRITE_RSP *pSMBr = (WRITE_RSP *)rsp_iov.iov_base;
                *nbytes = le16_to_cpu(pSMBr->CountHigh);
@@ -2209,13 +2215,15 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_lock_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), sizeof(*parm_data));
                        goto plk_err_exit;
                }
                data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                data_count  = le16_to_cpu(pSMBr->t2.DataCount);
                if (data_count < sizeof(struct cifs_posix_lock)) {
-                       rc = -EIO;
+                       rc = smb_EIO2(smb_eio_trace_lock_data_too_small,
+                                     data_count, sizeof(struct cifs_posix_lock));
                        goto plk_err_exit;
                }
                parm_data = (struct cifs_posix_lock *)
@@ -2774,7 +2782,8 @@ querySymLinkRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
                /* BB also check enough total bytes returned */
                if (rc || get_bcc(&pSMBr->hdr) < 2)
-                       rc = -EIO;
+                       rc = smb_EIO2(smb_eio_trace_qsym_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 2);
                else {
                        bool is_unicode;
                        u16 count = le16_to_cpu(pSMBr->t2.DataCount);
@@ -2876,13 +2885,15 @@ int cifs_query_reparse_point(const unsigned int xid,
        data_count = le32_to_cpu(io_rsp->DataCount);
        if (get_bcc(&io_rsp->hdr) < 2 || data_offset > 512 ||
            !data_count || data_count > 2048) {
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_qreparse_sizes_wrong,
+                             get_bcc(&io_rsp->hdr), data_count);
                goto error;
        }
 
        /* SetupCount must be 1, otherwise offset to ByteCount is incorrect. */
        if (io_rsp->SetupCount != 1) {
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_qreparse_setup_count,
+                             io_rsp->SetupCount, 1);
                goto error;
        }
 
@@ -2892,14 +2903,17 @@ int cifs_query_reparse_point(const unsigned int xid,
         * Check that we have full FSCTL_GET_REPARSE_POINT buffer.
         */
        if (data_count != le16_to_cpu(io_rsp->ReturnedDataLen)) {
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_qreparse_ret_datalen,
+                             data_count, le16_to_cpu(io_rsp->ReturnedDataLen));
                goto error;
        }
 
        end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
        start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
        if (start >= end) {
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_qreparse_data_area,
+                             (unsigned long)start - (unsigned long)io_rsp,
+                             (unsigned long)end - (unsigned long)io_rsp);
                goto error;
        }
 
@@ -2908,7 +2922,8 @@ int cifs_query_reparse_point(const unsigned int xid,
        len = sizeof(*buf);
        if (data_count < len ||
            data_count < le16_to_cpu(buf->ReparseDataLength) + len) {
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_qreparse_rep_datalen,
+                             data_count, le16_to_cpu(buf->ReparseDataLength) + len);
                goto error;
        }
 
@@ -3352,7 +3367,8 @@ queryAclRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
                /* BB also check enough total bytes returned */
                if (rc || get_bcc(&pSMBr->hdr) < 2)
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_getacl_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 2);
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
@@ -3525,7 +3541,8 @@ GetExtAttrRetry:
                if (rc || get_bcc(&pSMBr->hdr) < 2)
                        /* If rc should we check for EOPNOSUPP and
                           disable the srvino flag? or in caller? */
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_getextattr_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 2);
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
@@ -3533,7 +3550,8 @@ GetExtAttrRetry:
 
                        if (count != 16) {
                                cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
-                               rc = -EIO;
+                               rc = smb_EIO2(smb_eio_trace_getextattr_inv_size,
+                                             count, 16);
                                goto GetExtAttrOut;
                        }
                        pfinfo = (struct file_chattr_info *)
@@ -3700,7 +3718,8 @@ CIFSSMBGetCIFSACL(const unsigned int xid, struct cifs_tcon *tcon, __u16 fid,
                         pSMBr, parm, *acl_inf);
 
                if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_getcifsacl_param_count,
+                                     le32_to_cpu(pSMBr->ParameterCount), 4);
                        *pbuflen = 0;
                        goto qsec_out;
                }
@@ -3858,8 +3877,10 @@ QInfRetry:
                data->EndOfFile = data->AllocationSize;
                data->Attributes =
                        cpu_to_le32(le16_to_cpu(pSMBr->attr));
-       } else
-               rc = -EIO; /* bad buffer passed in */
+       } else {
+               /* bad buffer passed in */
+               rc = smb_EIO(smb_eio_trace_null_pointers);
+       }
 
        cifs_buf_release(pSMB);
 
@@ -3921,9 +3942,11 @@ QFileInfoRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc) /* BB add auto retry on EOPNOTSUPP? */
-                       rc = -EIO;
+                       rc = smb_EIO2(smb_eio_trace_qfileinfo_invalid,
+                                     get_bcc(&pSMBr->hdr), 40);
                else if (get_bcc(&pSMBr->hdr) < 40)
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_qfileinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 40);
                else if (pFindData) {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        memcpy((char *) pFindData,
@@ -4008,12 +4031,15 @@ QPathInfoRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc) /* BB add auto retry on EOPNOTSUPP? */
-                       rc = -EIO;
+                       rc = smb_EIO2(smb_eio_trace_qpathinfo_invalid,
+                                     get_bcc(&pSMBr->hdr), 40);
                else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 40);
                else if (legacy && get_bcc(&pSMBr->hdr) < 24)
-                       rc = -EIO;  /* 24 or 26 expected but we do not read
-                                       last field */
+                       /* 24 or 26 expected but we do not read last field */
+                       rc = smb_EIO2(smb_eio_trace_qpathinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 24);
                else if (data) {
                        int size;
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -4093,7 +4119,8 @@ UnixQFileInfoRetry:
 
                if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
                        cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_unixqfileinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
                } else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        memcpy((char *) pFindData,
@@ -4177,7 +4204,8 @@ UnixQPathInfoRetry:
 
                if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
                        cifs_dbg(VFS, "Malformed FILE_UNIX_BASIC_INFO response. Unix Extensions can be disabled on mount by specifying the nosfu mount option.\n");
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_unixqpathinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), sizeof(FILE_UNIX_BASIC_INFO));
                } else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        memcpy((char *) pFindData,
@@ -4580,7 +4608,8 @@ GetInodeNumberRetry:
                if (rc || get_bcc(&pSMBr->hdr) < 2)
                        /* If rc should we check for EOPNOSUPP and
                        disable the srvino flag? or in caller? */
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_getsrvinonum_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 2);
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
@@ -4588,7 +4617,8 @@ GetInodeNumberRetry:
                        /* BB Do we need a cast or hash here ? */
                        if (count < 8) {
                                cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
-                               rc = -EIO;
+                               rc = smb_EIO2(smb_eio_trace_getsrvinonum_size,
+                                             count, 8);
                                goto GetInodeNumOut;
                        }
                        pfinfo = (struct file_internal_info *)
@@ -4697,7 +4727,8 @@ getDFSRetry:
 
        /* BB Also check if enough total bytes returned? */
        if (rc || get_bcc(&pSMBr->hdr) < 17) {
-               rc = -EIO;      /* bad smb */
+               rc = smb_EIO2(smb_eio_trace_getdfsrefer_bcc_too_small,
+                             get_bcc(&pSMBr->hdr), 17);
                goto GetDFSRefExit;
        }
 
@@ -4773,7 +4804,8 @@ oldQFSInfoRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc || get_bcc(&pSMBr->hdr) < 18)
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_oldqfsinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 18);
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        cifs_dbg(FYI, "qfsinf resp BCC: %d  Offset %d\n",
@@ -4862,7 +4894,8 @@ QFSInfoRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc || get_bcc(&pSMBr->hdr) < 24)
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_qfsinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 24);
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
 
@@ -4952,7 +4985,8 @@ QFSAttributeRetry:
 
                if (rc || get_bcc(&pSMBr->hdr) < 13) {
                        /* BB also check if enough bytes returned */
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_qfsattrinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 13);
                } else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        response_data =
@@ -5025,7 +5059,9 @@ QFSDeviceRetry:
 
                if (rc || get_bcc(&pSMBr->hdr) <
                          sizeof(FILE_SYSTEM_DEVICE_INFO))
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_qfsdevinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr),
+                                     sizeof(FILE_SYSTEM_DEVICE_INFO));
                else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        response_data =
@@ -5096,7 +5132,8 @@ QFSUnixRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc || get_bcc(&pSMBr->hdr) < 13) {
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_qfsunixinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 13);
                } else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        response_data =
@@ -5244,7 +5281,8 @@ QFSPosixRetry:
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
                if (rc || get_bcc(&pSMBr->hdr) < 13) {
-                       rc = -EIO;      /* bad smb */
+                       rc = smb_EIO2(smb_eio_trace_qfsposixinfo_bcc_too_small,
+                                     get_bcc(&pSMBr->hdr), 13);
                } else {
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
                        response_data =
@@ -6044,7 +6082,8 @@ QAllEAsRetry:
 
        rc = validate_t2((struct smb_t2_rsp *)pSMBr);
        if (rc || get_bcc(&pSMBr->hdr) < 4) {
-               rc = -EIO;      /* bad smb */
+               rc = smb_EIO2(smb_eio_trace_qalleas_bcc_too_small,
+                             get_bcc(&pSMBr->hdr), 4);
                goto QAllEAsOut;
        }
 
@@ -6074,7 +6113,9 @@ QAllEAsRetry:
        end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
        if ((char *)ea_response_data + list_len > end_of_smb) {
                cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_qalleas_overlong,
+                             (unsigned long)ea_response_data + list_len - (unsigned long)pSMBr,
+                             (unsigned long)end_of_smb - (unsigned long)pSMBr);
                goto QAllEAsOut;
        }
 
@@ -6091,7 +6132,7 @@ QAllEAsRetry:
                /* make sure we can read name_len and value_len */
                if (list_len < 0) {
                        cifs_dbg(FYI, "EA entry goes beyond length of list\n");
-                       rc = -EIO;
+                       rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
                        goto QAllEAsOut;
                }
 
@@ -6100,7 +6141,7 @@ QAllEAsRetry:
                list_len -= name_len + 1 + value_len;
                if (list_len < 0) {
                        cifs_dbg(FYI, "EA entry goes beyond length of list\n");
-                       rc = -EIO;
+                       rc = smb_EIO1(smb_eio_trace_qalleas_ea_overlong, list_len);
                        goto QAllEAsOut;
                }
 
index 87a246efe695681f2989d166256cdf87f568a6e6..28d1cee90625051e76cbf2130093e183d1fc4725 100644 (file)
@@ -227,15 +227,15 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
        int rc = 0;
 
        if (WARN_ON_ONCE(in_len > 0xffffff))
-               return -EIO;
+               return smb_EIO1(smb_eio_trace_tx_too_long, in_len);
        if (ses == NULL) {
                cifs_dbg(VFS, "Null smb session\n");
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
        }
        server = ses->server;
        if (server == NULL) {
                cifs_dbg(VFS, "Null tcp session\n");
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
        }
 
        /* Ensure that we do not send more than 50 overlapping requests
@@ -245,7 +245,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
        if (in_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
                cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n",
                                in_len);
-               return -EIO;
+               return smb_EIO1(smb_eio_trace_tx_too_long, in_len);
        }
 
        rc = cifs_send_recv(xid, ses, ses->server,
index db709f5cd2e1ffecec3613537f0c0f8d678a00e1..f03dd980442706637506295b9668d400f09956be 100644 (file)
@@ -310,7 +310,7 @@ int smb_compress(struct TCP_Server_Info *server, struct smb_rqst *rq, compress_s
        iter = rq->rq_iter;
 
        if (!copy_from_iter_full(src, slen, &iter)) {
-               ret = -EIO;
+               ret = smb_EIO(smb_eio_trace_compress_copy);
                goto err_free;
        }
 
index 591096eb86726a4c88cbd008d0ac35d6892f1549..2f184e9d3c67ca768262b2eb1a8c85169e66136a 100644 (file)
@@ -3240,7 +3240,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
                if (be16_to_cpu(resp.length) != 0) {
                        cifs_dbg(VFS, "RFC 1002 positive session response but with invalid non-zero length %u\n",
                                 be16_to_cpu(resp.length));
-                       return -EIO;
+                       return smb_EIO(smb_eio_trace_rx_pos_sess_resp);
                }
                cifs_dbg(FYI, "RFC 1002 positive session response");
                break;
@@ -3279,17 +3279,18 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
                                break;
                        case RFC1002_INSUFFICIENT_RESOURCE:
                                /* remote server resource error */
+                               smb_EIO(smb_eio_trace_rx_insuff_res);
                                rc = -EREMOTEIO;
                                break;
                        case RFC1002_UNSPECIFIED_ERROR:
                        default:
                                /* other/unknown error */
-                               rc = -EIO;
+                               rc = smb_EIO(smb_eio_trace_rx_unspec_error);
                                break;
                        }
                } else {
                        cifs_dbg(VFS, "RFC 1002 negative session response\n");
-                       rc = -EIO;
+                       rc = smb_EIO(smb_eio_trace_rx_neg_sess_resp);
                }
                return rc;
        case RFC1002_RETARGET_SESSION_RESPONSE:
@@ -3311,7 +3312,7 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
                return -EMULTIHOP;
        default:
                cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", resp.type);
-               return -EIO;
+               return smb_EIO1(smb_eio_trace_rx_unknown_resp, resp.type);
        }
 
        server->with_rfc1001 = true;
@@ -4001,7 +4002,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
        __u16 bytes_left, count;
 
        if (ses == NULL)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        smb_buffer = cifs_buf_get();
        if (smb_buffer == NULL)
index da5597dbf5b9f140c6801158ac2357fa911c52ab..4ad69dc77e09bc62e79266cfa0082d845f4d0e68 100644 (file)
@@ -471,7 +471,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
        struct cifs_open_info_data buf = {};
 
        if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
 
        /*
         * Posix open is only called (at lookup time) for file create now. For
@@ -589,7 +589,7 @@ int cifs_create(struct mnt_idmap *idmap, struct inode *inode,
                 inode, direntry, direntry);
 
        if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) {
-               rc = -EIO;
+               rc = smb_EIO(smb_eio_trace_forced_shutdown);
                goto out_free_xid;
        }
 
@@ -631,7 +631,7 @@ int cifs_mknod(struct mnt_idmap *idmap, struct inode *inode,
 
        cifs_sb = CIFS_SB(inode->i_sb);
        if (unlikely(cifs_forced_shutdown(cifs_sb)))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
 
        tlink = cifs_sb_tlink(cifs_sb);
        if (IS_ERR(tlink))
index 9dc0a968ec89bfb1334319335250dc553706470f..7ff5cc9c5c5b74474af9ae607131ba8b449b4b82 100644 (file)
@@ -118,7 +118,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq)
        int rc;
 
        if (cifs_forced_shutdown(sbi)) {
-               rc = -EIO;
+               rc = smb_EIO(smb_eio_trace_forced_shutdown);
                goto fail;
        }
 
@@ -286,7 +286,7 @@ static int cifs_init_request(struct netfs_io_request *rreq, struct file *file)
                        req->pid = req->cfile->pid;
        } else if (rreq->origin != NETFS_WRITEBACK) {
                WARN_ON_ONCE(1);
-               return -EIO;
+               return smb_EIO1(smb_eio_trace_not_netfs_writeback, rreq->origin);
        }
 
        return 0;
@@ -1036,7 +1036,7 @@ int cifs_open(struct inode *inode, struct file *file)
        cifs_sb = CIFS_SB(inode->i_sb);
        if (unlikely(cifs_forced_shutdown(cifs_sb))) {
                free_xid(xid);
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
        }
 
        tlink = cifs_sb_tlink(cifs_sb);
index 400e4fbd450f6431014350efd72e9e24cccb20e7..f9ee95953fa4a52d6b479033e9a26286da2eb71c 100644 (file)
@@ -1952,7 +1952,7 @@ static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyren
        cifs_dbg(FYI, "cifs_unlink, dir=0x%p, dentry=0x%p\n", dir, dentry);
 
        if (unlikely(cifs_forced_shutdown(cifs_sb)))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
 
        /* Unhash dentry in advance to prevent any concurrent opens */
        spin_lock(&dentry->d_lock);
@@ -2268,7 +2268,7 @@ struct dentry *cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,
 
        cifs_sb = CIFS_SB(inode->i_sb);
        if (unlikely(cifs_forced_shutdown(cifs_sb)))
-               return ERR_PTR(-EIO);
+               return ERR_PTR(smb_EIO(smb_eio_trace_forced_shutdown));
        tlink = cifs_sb_tlink(cifs_sb);
        if (IS_ERR(tlink))
                return ERR_CAST(tlink);
@@ -2354,7 +2354,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
 
        cifs_sb = CIFS_SB(inode->i_sb);
        if (unlikely(cifs_forced_shutdown(cifs_sb))) {
-               rc = -EIO;
+               rc = smb_EIO(smb_eio_trace_forced_shutdown);
                goto rmdir_exit;
        }
 
@@ -2516,7 +2516,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir,
 
        cifs_sb = CIFS_SB(source_dir->i_sb);
        if (unlikely(cifs_forced_shutdown(cifs_sb)))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
 
        /*
         * Prevent any concurrent opens on the target by unhashing the dentry.
@@ -2901,7 +2901,7 @@ int cifs_getattr(struct mnt_idmap *idmap, const struct path *path,
        int rc;
 
        if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
 
        /*
         * We need to be sure that all dirty pages are written and the server
@@ -2976,7 +2976,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start,
        int rc;
 
        if (unlikely(cifs_forced_shutdown(cifs_sb)))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
 
        /*
         * We need to be sure that all dirty pages are written as they
@@ -3468,7 +3468,7 @@ cifs_setattr(struct mnt_idmap *idmap, struct dentry *direntry,
 #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
 
        if (unlikely(cifs_forced_shutdown(cifs_sb)))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
        /*
         * Avoid setting [cm]time with O_TRUNC to prevent the server from
         * disabling automatic timestamp updates as specified in
index 70f3c0c67eebd11b675b62277ab604c439d1bb80..fdfdc9a3abdd5ac4b33f9d5b2fcba6c8720185c8 100644 (file)
@@ -160,7 +160,8 @@ create_mf_symlink(const unsigned int xid, struct cifs_tcon *tcon,
                goto out;
 
        if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_symlink_file_size,
+                             bytes_written, CIFS_MF_SYMLINK_FILE_SIZE);
 out:
        kfree(buf);
        return rc;
@@ -424,7 +425,8 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
 
        /* Make sure we wrote all of the symlink data */
        if ((rc == 0) && (*pbytes_written != CIFS_MF_SYMLINK_FILE_SIZE))
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_short_symlink_write,
+                             *pbytes_written, CIFS_MF_SYMLINK_FILE_SIZE);
 
        SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 
@@ -451,7 +453,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
        struct cifsInodeInfo *cifsInode;
 
        if (unlikely(cifs_forced_shutdown(cifs_sb)))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
 
        tlink = cifs_sb_tlink(cifs_sb);
        if (IS_ERR(tlink))
@@ -553,7 +555,7 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode,
        struct inode *newinode = NULL;
 
        if (unlikely(cifs_forced_shutdown(cifs_sb)))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
 
        page = alloc_dentry_path();
        if (!page)
index a026dfd68d377184a28de569645a28876a776e52..eb7368367c143009975256a99da536ab7e13db5a 100644 (file)
@@ -379,25 +379,29 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
                                return 0;
                        }
                        cifs_dbg(VFS, "rcvd invalid byte count (bcc)\n");
+                       return smb_EIO1(smb_eio_trace_rx_inv_bcc, tmp[sizeof(struct smb_hdr)]);
                } else {
                        cifs_dbg(VFS, "Length less than smb header size\n");
+                       return smb_EIO2(smb_eio_trace_rx_too_short,
+                                       total_read, smb->WordCount);
                }
-               return -EIO;
        } else if (total_read < sizeof(*smb) + 2 * smb->WordCount) {
                cifs_dbg(VFS, "%s: can't read BCC due to invalid WordCount(%u)\n",
                         __func__, smb->WordCount);
-               return -EIO;
+               return smb_EIO2(smb_eio_trace_rx_check_rsp,
+                               total_read, 2 + sizeof(struct smb_hdr));
        }
 
        /* otherwise, there is enough to get to the BCC */
        if (check_smb_hdr(smb))
-               return -EIO;
+               return smb_EIO1(smb_eio_trace_rx_rfc1002_magic, *(u32 *)smb->Protocol);
        clc_len = smbCalcSize(smb);
 
        if (rfclen != total_read) {
                cifs_dbg(VFS, "Length read does not match RFC1001 length %d/%d\n",
                         rfclen, total_read);
-               return -EIO;
+               return smb_EIO2(smb_eio_trace_rx_check_rsp,
+                               total_read, rfclen);
        }
 
        if (rfclen != clc_len) {
@@ -414,7 +418,8 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
                if (rfclen < clc_len) {
                        cifs_dbg(VFS, "RFC1001 size %u smaller than SMB for mid=%u\n",
                                 rfclen, mid);
-                       return -EIO;
+                       return smb_EIO2(smb_eio_trace_rx_calc_len_too_big,
+                                       rfclen, clc_len);
                } else if (rfclen > clc_len + 512) {
                        /*
                         * Some servers (Windows XP in particular) send more
@@ -427,7 +432,8 @@ checkSMB(char *buf, unsigned int pdu_len, unsigned int total_read,
                         */
                        cifs_dbg(VFS, "RFC1001 size %u more than 512 bytes larger than SMB for mid=%u\n",
                                 rfclen, mid);
-                       return -EIO;
+                       return smb_EIO2(smb_eio_trace_rx_overlong,
+                                       rfclen, clc_len + 512);
                }
        }
        return 0;
index ba8a92b430c1b146e8d26c91c1d6a2148de20aec..e5a465a018c046e6a0b5dbdc507eb97c1f951024 100644 (file)
@@ -885,6 +885,10 @@ map_smb_to_linux_error(char *buf, bool logErr)
        /* generic corrective action e.g. reconnect SMB session on
         * ERRbaduid could be added */
 
+       if (rc == -EIO)
+               smb_EIO2(smb_eio_trace_smb1_received_error,
+                        le32_to_cpu(smb->Status.CifsError),
+                        le16_to_cpu(smb->Flags2));
        return rc;
 }
 
index 7ff728503ed1d93c629ea0ad2cfe3a16ef87ebc0..6844f1dc3921658b46e6af738ba620e0a4008f03 100644 (file)
@@ -775,7 +775,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
 
                if (cfile->srch_inf.ntwrk_buf_start == NULL) {
                        cifs_dbg(VFS, "ntwrk_buf_start is NULL during readdir\n");
-                       return -EIO;
+                       return smb_EIO(smb_eio_trace_null_pointers);
                }
 
                end_of_smb = cfile->srch_inf.ntwrk_buf_start +
index 10c84c095fe783d8f8783f7740b54f885ca76e35..ce9b923498b56d14f6a668fd1b073a9a38cdfca4 100644 (file)
@@ -732,7 +732,8 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
        len = le16_to_cpu(buf->ReparseDataLength);
        if (len < sizeof(buf->InodeType)) {
                cifs_dbg(VFS, "srv returned malformed nfs buffer\n");
-               return -EIO;
+               return smb_EIO2(smb_eio_trace_reparse_nfs_too_short,
+                               len, sizeof(buf->InodeType));
        }
 
        len -= sizeof(buf->InodeType);
@@ -741,7 +742,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
        case NFS_SPECFILE_LNK:
                if (len == 0 || (len % 2)) {
                        cifs_dbg(VFS, "srv returned malformed nfs symlink buffer\n");
-                       return -EIO;
+                       return smb_EIO1(smb_eio_trace_reparse_nfs_symbuf, len);
                }
                /*
                 * Check that buffer does not contain UTF-16 null codepoint
@@ -749,7 +750,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
                 */
                if (UniStrnlen((wchar_t *)buf->DataBuffer, len/2) != len/2) {
                        cifs_dbg(VFS, "srv returned null byte in nfs symlink target location\n");
-                       return -EIO;
+                       return smb_EIO1(smb_eio_trace_reparse_nfs_nul, len);
                }
                data->symlink_target = cifs_strndup_from_utf16(buf->DataBuffer,
                                                               len, true,
@@ -764,7 +765,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
                /* DataBuffer for block and char devices contains two 32-bit numbers */
                if (len != 8) {
                        cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
-                       return -EIO;
+                       return smb_EIO1(smb_eio_trace_reparse_nfs_dev, len);
                }
                break;
        case NFS_SPECFILE_FIFO:
@@ -772,7 +773,7 @@ static int parse_reparse_nfs(struct reparse_nfs_data_buffer *buf,
                /* DataBuffer for fifos and sockets is empty */
                if (len != 0) {
                        cifs_dbg(VFS, "srv returned malformed nfs buffer for type: 0x%llx\n", type);
-                       return -EIO;
+                       return smb_EIO1(smb_eio_trace_reparse_nfs_sockfifo, len);
                }
                break;
        default:
@@ -796,13 +797,13 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
        int abs_path_len;
        char *abs_path;
        int levels;
-       int rc;
+       int rc, ulen;
        int i;
 
        /* Check that length it valid */
        if (!len || (len % 2)) {
                cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_reparse_native_nul, len);
                goto out;
        }
 
@@ -810,9 +811,10 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len,
         * Check that buffer does not contain UTF-16 null codepoint
         * because Linux cannot process symlink with null byte.
         */
-       if (UniStrnlen((wchar_t *)buf, len/2) != len/2) {
+       ulen = UniStrnlen((wchar_t *)buf, len/2);
+       if (ulen != len/2) {
                cifs_dbg(VFS, "srv returned null byte in native symlink target location\n");
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_reparse_native_nul, ulen, len);
                goto out;
        }
 
@@ -996,7 +998,8 @@ static int parse_reparse_native_symlink(struct reparse_symlink_data_buffer *sym,
        len = le16_to_cpu(sym->SubstituteNameLength);
        if (offs + 20 > plen || offs + len + 20 > plen) {
                cifs_dbg(VFS, "srv returned malformed symlink buffer\n");
-               return -EIO;
+               return smb_EIO2(smb_eio_trace_reparse_native_sym_len,
+                               offs << 16 | len, plen);
        }
 
        return smb2_parse_native_symlink(&data->symlink_target,
@@ -1019,13 +1022,16 @@ static int parse_reparse_wsl_symlink(struct reparse_wsl_symlink_data_buffer *buf
 
        if (len <= data_offset) {
                cifs_dbg(VFS, "srv returned malformed wsl symlink buffer\n");
-               return -EIO;
+               return smb_EIO2(smb_eio_trace_reparse_wsl_symbuf,
+                               len, data_offset);
        }
 
        /* MS-FSCC 2.1.2.7 defines layout of the Target field only for Version 2. */
-       if (le32_to_cpu(buf->Version) != 2) {
-               cifs_dbg(VFS, "srv returned unsupported wsl symlink version %u\n", le32_to_cpu(buf->Version));
-               return -EIO;
+       u32 version = le32_to_cpu(buf->Version);
+
+       if (version != 2) {
+               cifs_dbg(VFS, "srv returned unsupported wsl symlink version %u\n", version);
+               return smb_EIO1(smb_eio_trace_reparse_wsl_ver, version);
        }
 
        /* Target for Version 2 is in UTF-8 but without trailing null-term byte */
@@ -1034,9 +1040,12 @@ static int parse_reparse_wsl_symlink(struct reparse_wsl_symlink_data_buffer *buf
         * Check that buffer does not contain null byte
         * because Linux cannot process symlink with null byte.
         */
-       if (strnlen(buf->Target, symname_utf8_len) != symname_utf8_len) {
+       size_t ulen = strnlen(buf->Target, symname_utf8_len);
+
+       if (ulen != symname_utf8_len) {
                cifs_dbg(VFS, "srv returned null byte in wsl symlink target location\n");
-               return -EIO;
+               return smb_EIO2(smb_eio_trace_reparse_wsl_ver,
+                               ulen, symname_utf8_len);
        }
        symname_utf16 = kzalloc(symname_utf8_len * 2, GFP_KERNEL);
        if (!symname_utf16)
@@ -1083,13 +1092,17 @@ int parse_reparse_point(struct reparse_data_buffer *buf,
        case IO_REPARSE_TAG_AF_UNIX:
        case IO_REPARSE_TAG_LX_FIFO:
        case IO_REPARSE_TAG_LX_CHR:
-       case IO_REPARSE_TAG_LX_BLK:
-               if (le16_to_cpu(buf->ReparseDataLength) != 0) {
+       case IO_REPARSE_TAG_LX_BLK: {
+               u16 dlen = le16_to_cpu(buf->ReparseDataLength);
+
+               if (dlen != 0) {
+                       u32 rtag = le32_to_cpu(buf->ReparseTag);
                        cifs_dbg(VFS, "srv returned malformed buffer for reparse point: 0x%08x\n",
-                                le32_to_cpu(buf->ReparseTag));
-                       return -EIO;
+                                rtag);
+                       return smb_EIO2(smb_eio_trace_reparse_data_len, dlen, rtag);
                }
                return 0;
+       }
        default:
                return -EOPNOTSUPP;
        }
index 752dee5a020cfd55ab783f3c932a551f75161bbd..3e39faf637861baa9fa756348d4bbc41cd4a3570 100644 (file)
@@ -1503,7 +1503,7 @@ sess_auth_ntlmv2(struct sess_data *sess_data)
        smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
 
        if (smb_buf->WordCount != 3) {
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_sess_nl2_wcc, smb_buf->WordCount);
                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
                goto out;
        }
@@ -1629,7 +1629,7 @@ sess_auth_kerberos(struct sess_data *sess_data)
        smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
 
        if (smb_buf->WordCount != 4) {
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_sess_krb_wcc, smb_buf->WordCount);
                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
                goto out_put_spnego_key;
        }
@@ -1790,7 +1790,7 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data)
        cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
 
        if (smb_buf->WordCount != 4) {
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_sess_rawnl_neg_wcc, smb_buf->WordCount);
                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
                goto out_free_ntlmsspblob;
        }
@@ -1880,7 +1880,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
        pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
        smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base;
        if (smb_buf->WordCount != 4) {
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_sess_rawnl_auth_wcc, smb_buf->WordCount);
                cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount);
                goto out_free_ntlmsspblob;
        }
index a7f6292388306c72f183b0351b454808ca814047..68d37f11f3f3d5d5f16ac7f2e62d6ebd8a0b3983 100644 (file)
@@ -76,11 +76,11 @@ int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_i
                return 0;
 
        if (!*target)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        len = strlen(*target);
        if (!len)
-               return -EIO;
+               return smb_EIO1(smb_eio_trace_sym_target_len, len);
 
        /*
         * If this is directory symlink and it does not have trailing slash then
@@ -104,7 +104,7 @@ int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_i
         * both Windows and Linux systems. So return an error for such symlink.
         */
        if (!directory && (*target)[len-1] == '/')
-               return -EIO;
+               return smb_EIO(smb_eio_trace_sym_slash);
 
        return 0;
 }
index d0aad4821ed4d946ed6dfb107d0015c64c6fa732..3e45e41f5713b96862783ab5123a78cfada978ee 100644 (file)
@@ -31,16 +31,20 @@ static struct reparse_data_buffer *reparse_buf_ptr(struct kvec *iov)
        struct reparse_data_buffer *buf;
        struct smb2_ioctl_rsp *io = iov->iov_base;
        u32 off, count, len;
+       u16 rdlen;
 
        count = le32_to_cpu(io->OutputCount);
        off = le32_to_cpu(io->OutputOffset);
        if (check_add_overflow(off, count, &len) || len > iov->iov_len)
-               return ERR_PTR(-EIO);
+               return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_overlong,
+                                       off, count));
 
        buf = (struct reparse_data_buffer *)((u8 *)io + off);
        len = sizeof(*buf);
-       if (count < len || count < le16_to_cpu(buf->ReparseDataLength) + len)
-               return ERR_PTR(-EIO);
+       rdlen = le16_to_cpu(buf->ReparseDataLength);
+
+       if (count < len || count < rdlen + len)
+               return ERR_PTR(smb_EIO2(smb_eio_trace_reparse_rdlen, count, rdlen));
        return buf;
 }
 
@@ -1635,7 +1639,7 @@ int smb2_rename_pending_delete(const char *full_path,
        } else {
                cifs_tcon_dbg(FYI, "%s: failed to rename '%s' to '%s': %d\n",
                              __func__, full_path, to_name, rc);
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_pend_del_fail, rc);
        }
 out:
        cifs_put_tlink(tlink);
index 12c2b868789fdac0881d537225a870b118349d74..b179d7369fbac4654616563cc7f6982c4d4e6f68 100644 (file)
@@ -9,6 +9,7 @@
  */
 #include <linux/errno.h>
 #include "cifsglob.h"
+#include "cifsproto.h"
 #include "cifs_debug.h"
 #include "smb2pdu.h"
 #include "smb2proto.h"
@@ -2477,5 +2478,7 @@ map_smb2_to_linux_error(char *buf, bool log_err)
                           le16_to_cpu(shdr->Command),
                           le64_to_cpu(shdr->MessageId),
                           le32_to_cpu(smb2err), rc);
+       if (rc == -EIO)
+               smb_EIO1(smb_eio_trace_smb2_received_error, le32_to_cpu(smb2err));
        return rc;
 }
index 760edb98ed64d282bb4d66e78bf1514810488a0e..3328d6a8903808bbf18c568176125c6849988198 100644 (file)
@@ -1046,7 +1046,8 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
 
                if (src_size < 8 + name_len + 1 + value_len) {
                        cifs_dbg(FYI, "EA entry goes beyond length of list\n");
-                       rc = -EIO;
+                       rc = smb_EIO2(smb_eio_trace_ea_overrun,
+                                     src_size, 8 + name_len + 1 + value_len);
                        goto out;
                }
 
@@ -1607,7 +1608,7 @@ replay_again:
        }
 
        if (!ses || !server) {
-               rc = -EIO;
+               rc = smb_EIO(smb_eio_trace_null_pointers);
                goto free_vars;
        }
 
@@ -1942,7 +1943,7 @@ retry:
                if (unlikely(ret_data_len != sizeof(*cc_rsp))) {
                        cifs_tcon_dbg(VFS, "Copychunk invalid response: size %u/%zu\n",
                                      ret_data_len, sizeof(*cc_rsp));
-                       rc = -EIO;
+                       rc = smb_EIO1(smb_eio_trace_copychunk_inv_rsp, ret_data_len);
                        goto out;
                }
 
@@ -1952,11 +1953,18 @@ retry:
 
                if (rc == 0) {
                        /* Check if server claimed to write more than we asked */
-                       if (unlikely(!bytes_written || bytes_written > copy_bytes ||
-                                    !chunks_written || chunks_written > chunks)) {
-                               cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u, chunks written %u/%u\n",
-                                             bytes_written, copy_bytes, chunks_written, chunks);
-                               rc = -EIO;
+                       if (unlikely(!bytes_written || bytes_written > copy_bytes)) {
+                               cifs_tcon_dbg(VFS, "Copychunk invalid response: bytes written %u/%u\n",
+                                             bytes_written, copy_bytes);
+                               rc = smb_EIO2(smb_eio_trace_copychunk_overcopy_b,
+                                             bytes_written, copy_bytes);
+                               goto out;
+                       }
+                       if (unlikely(!chunks_written || chunks_written > chunks)) {
+                               cifs_tcon_dbg(VFS, "Copychunk invalid response: chunks written %u/%u\n",
+                                             chunks_written, chunks);
+                               rc = smb_EIO2(smb_eio_trace_copychunk_overcopy_c,
+                                             chunks_written, chunks);
                                goto out;
                        }
 
@@ -3127,7 +3135,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
        }
 
        if (!rc && !dfs_rsp)
-               rc = -EIO;
+               rc = smb_EIO(smb_eio_trace_dfsref_no_rsp);
        if (rc) {
                if (!is_retryable_error(rc) && rc != -ENOENT && rc != -EOPNOTSUPP)
                        cifs_tcon_dbg(FYI, "%s: ioctl error: rc=%d\n", __func__, rc);
@@ -4555,7 +4563,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
                                             buffer, 0, 0, size);
 
                        if (!cifs_copy_iter_to_folioq(&old->rq_iter, size, buffer)) {
-                               rc = -EIO;
+                               rc = smb_EIO1(smb_eio_trace_tx_copy_iter_to_buf, size);
                                goto err_free;
                        }
                }
@@ -4656,7 +4664,8 @@ cifs_copy_folioq_to_iter(struct folio_queue *folioq, size_t data_size,
                        n = copy_folio_to_iter(folio, skip, len, iter);
                        if (n != len) {
                                cifs_dbg(VFS, "%s: something went wrong\n", __func__);
-                               return -EIO;
+                               return smb_EIO2(smb_eio_trace_rx_copy_to_iter,
+                                               n, len);
                        }
                        data_size -= n;
                        skip = 0;
@@ -4739,7 +4748,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
                /* data_offset is beyond the end of smallbuf */
                cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
                         __func__, data_offset);
-               rdata->result = -EIO;
+               rdata->result = smb_EIO1(smb_eio_trace_rx_overlong, data_offset);
                if (is_offloaded)
                        mid->mid_state = MID_RESPONSE_MALFORMED;
                else
@@ -4758,7 +4767,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
                        /* data offset is beyond the 1st page of response */
                        cifs_dbg(FYI, "%s: data offset (%u) beyond 1st page of response\n",
                                 __func__, data_offset);
-                       rdata->result = -EIO;
+                       rdata->result = smb_EIO1(smb_eio_trace_rx_overpage, data_offset);
                        if (is_offloaded)
                                mid->mid_state = MID_RESPONSE_MALFORMED;
                        else
@@ -4768,7 +4777,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
 
                if (data_len > buffer_len - pad_len) {
                        /* data_len is corrupt -- discard frame */
-                       rdata->result = -EIO;
+                       rdata->result = smb_EIO1(smb_eio_trace_rx_bad_datalen, data_len);
                        if (is_offloaded)
                                mid->mid_state = MID_RESPONSE_MALFORMED;
                        else
@@ -4793,12 +4802,12 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
                WARN_ONCE(buffer, "read data can be either in buf or in buffer");
                copied = copy_to_iter(buf + data_offset, data_len, &rdata->subreq.io_iter);
                if (copied == 0)
-                       return -EIO;
+                       return smb_EIO2(smb_eio_trace_rx_copy_to_iter, copied, data_len);
                rdata->got_bytes = copied;
        } else {
                /* read response payload cannot be in both buf and pages */
                WARN_ONCE(1, "buf can not contain only a part of read data");
-               rdata->result = -EIO;
+               rdata->result = smb_EIO(smb_eio_trace_rx_both_buf);
                if (is_offloaded)
                        mid->mid_state = MID_RESPONSE_MALFORMED;
                else
index 40611af4221029336a3f2c8c8839c5e809ab7873..7d041dc168247aaa58662ff47730c9d5c891133c 100644 (file)
@@ -249,15 +249,15 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
 
        ses = tcon->ses;
        if (!ses)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
        spin_lock(&ses->ses_lock);
        if (ses->ses_status == SES_EXITING) {
                spin_unlock(&ses->ses_lock);
-               return -EIO;
+               return smb_EIO(smb_eio_trace_sess_exiting);
        }
        spin_unlock(&ses->ses_lock);
        if (!ses->server || !server)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        spin_lock(&server->srv_lock);
        if (server->tcpStatus == CifsNeedReconnect) {
@@ -1061,7 +1061,7 @@ SMB2_negotiate(const unsigned int xid,
 
        if (!server) {
                WARN(1, "%s: server is NULL!\n", __func__);
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
        }
 
        rc = smb2_plain_req_init(SMB2_NEGOTIATE, NULL, server,
@@ -1142,64 +1142,84 @@ SMB2_negotiate(const unsigned int xid,
        } else if (rc != 0)
                goto neg_exit;
 
-       rc = -EIO;
+       u16 dialect = le16_to_cpu(rsp->DialectRevision);
        if (strcmp(server->vals->version_string,
                   SMB3ANY_VERSION_STRING) == 0) {
-               if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
+               switch (dialect) {
+               case SMB20_PROT_ID:
                        cifs_server_dbg(VFS,
                                "SMB2 dialect returned but not requested\n");
+                       rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 3);
                        goto neg_exit;
-               } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
+               case SMB21_PROT_ID:
                        cifs_server_dbg(VFS,
                                "SMB2.1 dialect returned but not requested\n");
+                       rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 3);
                        goto neg_exit;
-               } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
+               case SMB311_PROT_ID:
                        /* ops set to 3.0 by default for default so update */
                        server->ops = &smb311_operations;
                        server->vals = &smb311_values;
+                       break;
+               default:
+                       break;
                }
        } else if (strcmp(server->vals->version_string,
-                  SMBDEFAULT_VERSION_STRING) == 0) {
-               if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
+                         SMBDEFAULT_VERSION_STRING) == 0) {
+               switch (dialect) {
+               case SMB20_PROT_ID:
                        cifs_server_dbg(VFS,
                                "SMB2 dialect returned but not requested\n");
+                       rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect, dialect, 0);
                        goto neg_exit;
-               } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
+               case SMB21_PROT_ID:
                        /* ops set to 3.0 by default for default so update */
                        server->ops = &smb21_operations;
                        server->vals = &smb21_values;
-               } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
+                       break;
+               case SMB311_PROT_ID:
                        server->ops = &smb311_operations;
                        server->vals = &smb311_values;
+                       break;
+               default:
+                       break;
                }
-       } else if (le16_to_cpu(rsp->DialectRevision) !=
-                               server->vals->protocol_id) {
+       } else if (dialect != server->vals->protocol_id) {
                /* if requested single dialect ensure returned dialect matched */
                cifs_server_dbg(VFS, "Invalid 0x%x dialect returned: not requested\n",
-                               le16_to_cpu(rsp->DialectRevision));
+                               dialect);
+               rc = smb_EIO2(smb_eio_trace_neg_unreq_dialect,
+                             dialect, server->vals->protocol_id);
                goto neg_exit;
        }
 
        cifs_dbg(FYI, "mode 0x%x\n", rsp->SecurityMode);
 
-       if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID))
+       switch (dialect) {
+       case SMB20_PROT_ID:
                cifs_dbg(FYI, "negotiated smb2.0 dialect\n");
-       else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID))
+               break;
+       case SMB21_PROT_ID:
                cifs_dbg(FYI, "negotiated smb2.1 dialect\n");
-       else if (rsp->DialectRevision == cpu_to_le16(SMB30_PROT_ID))
+               break;
+       case SMB30_PROT_ID:
                cifs_dbg(FYI, "negotiated smb3.0 dialect\n");
-       else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID))
+               break;
+       case SMB302_PROT_ID:
                cifs_dbg(FYI, "negotiated smb3.02 dialect\n");
-       else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
+               break;
+       case SMB311_PROT_ID:
                cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n");
-       else {
+               break;
+       default:
                cifs_server_dbg(VFS, "Invalid dialect returned by server 0x%x\n",
-                               le16_to_cpu(rsp->DialectRevision));
+                               dialect);
+               rc = smb_EIO1(smb_eio_trace_neg_inval_dialect, dialect);
                goto neg_exit;
        }
 
        rc = 0;
-       server->dialect = le16_to_cpu(rsp->DialectRevision);
+       server->dialect = dialect;
 
        /*
         * Keep a copy of the hash after negprot. This hash will be
@@ -1255,10 +1275,10 @@ SMB2_negotiate(const unsigned int xid,
                if (rc == 1)
                        rc = 0;
                else if (rc == 0)
-                       rc = -EIO;
+                       rc = smb_EIO1(smb_eio_trace_neg_decode_token, rc);
        }
 
-       if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
+       if (server->dialect == SMB311_PROT_ID) {
                if (rsp->NegotiateContextCount)
                        rc = smb311_decode_neg_context(rsp, server,
                                                       rsp_iov.iov_len);
@@ -1371,32 +1391,47 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
        } else if (rc != 0) {
                cifs_tcon_dbg(VFS, "validate protocol negotiate failed: %d\n",
                              rc);
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_neg_info_fail, rc);
                goto out_free_inbuf;
        }
 
-       rc = -EIO;
        if (rsplen != sizeof(*pneg_rsp)) {
                cifs_tcon_dbg(VFS, "Invalid protocol negotiate response size: %d\n",
                              rsplen);
 
                /* relax check since Mac returns max bufsize allowed on ioctl */
-               if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp))
+               if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp)) {
+                       rc = smb_EIO1(smb_eio_trace_neg_bad_rsplen, rsplen);
                        goto out_free_rsp;
+               }
        }
 
        /* check validate negotiate info response matches what we got earlier */
-       if (pneg_rsp->Dialect != cpu_to_le16(server->dialect))
+       u16 dialect = le16_to_cpu(pneg_rsp->Dialect);
+
+       if (dialect != server->dialect) {
+               rc = smb_EIO2(smb_eio_trace_neg_info_dialect,
+                             dialect, server->dialect);
                goto vneg_out;
+       }
 
-       if (pneg_rsp->SecurityMode != cpu_to_le16(server->sec_mode))
+       u16 sec_mode = le16_to_cpu(pneg_rsp->SecurityMode);
+
+       if (sec_mode != server->sec_mode) {
+               rc = smb_EIO2(smb_eio_trace_neg_info_sec_mode,
+                             sec_mode, server->sec_mode);
                goto vneg_out;
+       }
 
        /* do not validate server guid because not saved at negprot time yet */
+       u32 caps = le32_to_cpu(pneg_rsp->Capabilities);
 
-       if ((le32_to_cpu(pneg_rsp->Capabilities) | SMB2_NT_FIND |
-             SMB2_LARGE_FILES) != server->capabilities)
+       if ((caps | SMB2_NT_FIND |
+            SMB2_LARGE_FILES) != server->capabilities) {
+               rc = smb_EIO2(smb_eio_trace_neg_info_caps,
+                             caps, server->capabilities);
                goto vneg_out;
+       }
 
        /* validate negotiate successful */
        rc = 0;
@@ -1758,11 +1793,11 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
        if (rc)
                goto out;
 
-       if (offsetof(struct smb2_sess_setup_rsp, Buffer) !=
-                       le16_to_cpu(rsp->SecurityBufferOffset)) {
-               cifs_dbg(VFS, "Invalid security buffer offset %d\n",
-                       le16_to_cpu(rsp->SecurityBufferOffset));
-               rc = -EIO;
+       u16 boff = le16_to_cpu(rsp->SecurityBufferOffset);
+
+       if (offsetof(struct smb2_sess_setup_rsp, Buffer) != boff) {
+               cifs_dbg(VFS, "Invalid security buffer offset %d\n", boff);
+               rc = smb_EIO1(smb_eio_trace_sess_buf_off, boff);
                goto out;
        }
        rc = decode_ntlmssp_challenge(rsp->Buffer,
@@ -1916,7 +1951,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
 
        if (!server) {
                WARN(1, "%s: server is NULL!\n", __func__);
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
        }
 
        sess_data = kzalloc(sizeof(struct SMB2_sess_data), GFP_KERNEL);
@@ -1966,10 +2001,9 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
 
        cifs_dbg(FYI, "disconnect session %p\n", ses);
 
-       if (ses && (ses->server))
-               server = ses->server;
-       else
-               return -EIO;
+       if (!ses || !ses->server)
+               return smb_EIO(smb_eio_trace_null_pointers);
+       server = ses->server;
 
        /* no need to send SMB logoff if uid already closed due to reconnect */
        spin_lock(&ses->chan_lock);
@@ -2048,7 +2082,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
        cifs_dbg(FYI, "TCON\n");
 
        if (!server || !tree)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
        if (unc_path == NULL)
@@ -2186,7 +2220,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
        cifs_dbg(FYI, "Tree Disconnect\n");
 
        if (!ses || !(ses->server))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        trace_smb3_tdis_enter(xid, tcon->tid, ses->Suid, tcon->tree_name);
        spin_lock(&ses->chan_lock);
@@ -2856,7 +2890,7 @@ replay_again:
                return -ENOMEM;
 
        if (!ses || !server) {
-               rc = -EIO;
+               rc = smb_EIO(smb_eio_trace_null_pointers);
                goto err_free_path;
        }
 
@@ -2973,7 +3007,7 @@ replay_again:
         */
        rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
        if (rsp == NULL) {
-               rc = -EIO;
+               rc = smb_EIO(smb_eio_trace_mkdir_no_rsp);
                kfree(pc_buf);
                goto err_free_req;
        }
@@ -3211,7 +3245,7 @@ replay_again:
 
        cifs_dbg(FYI, "create/open\n");
        if (!ses || !server)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        if (smb3_encryption_required(tcon))
                flags |= CIFS_TRANSFORM_REQ;
@@ -3417,11 +3451,11 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
        int retries = 0, cur_sleep = 1;
 
        if (!tcon)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        ses = tcon->ses;
        if (!ses)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
 replay_again:
        /* reinitialize for possible replay */
@@ -3429,7 +3463,7 @@ replay_again:
        server = cifs_pick_channel(ses);
 
        if (!server)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        cifs_dbg(FYI, "SMB2 IOCTL\n");
 
@@ -3492,7 +3526,7 @@ replay_again:
         * warning)
         */
        if (rsp == NULL) {
-               rc = -EIO;
+               rc = smb_EIO(smb_eio_trace_ioctl_no_rsp);
                goto ioctl_exit;
        }
 
@@ -3503,16 +3537,18 @@ replay_again:
                goto ioctl_exit; /* server returned no data */
        else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) {
                cifs_tcon_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen);
+               rc = smb_EIO2(smb_eio_trace_ioctl_data_len, *plen, rsp_iov.iov_len);
                *plen = 0;
-               rc = -EIO;
                goto ioctl_exit;
        }
 
-       if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) {
-               cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen,
-                       le32_to_cpu(rsp->OutputOffset));
+       u32 outoff = le32_to_cpu(rsp->OutputOffset);
+
+       if (rsp_iov.iov_len - *plen < outoff) {
+               cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n",
+                             *plen, outoff);
+               rc = smb_EIO2(smb_eio_trace_ioctl_out_off, rsp_iov.iov_len - *plen, outoff);
                *plen = 0;
-               rc = -EIO;
                goto ioctl_exit;
        }
 
@@ -3620,7 +3656,7 @@ replay_again:
        cifs_dbg(FYI, "Close\n");
 
        if (!ses || !server)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        if (smb3_encryption_required(tcon))
                flags |= CIFS_TRANSFORM_REQ;
@@ -3817,7 +3853,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
        cifs_dbg(FYI, "Query Info\n");
 
        if (!ses)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
 replay_again:
        /* reinitialize for possible replay */
@@ -3826,7 +3862,7 @@ replay_again:
        server = cifs_pick_channel(ses);
 
        if (!server)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        if (smb3_encryption_required(tcon))
                flags |= CIFS_TRANSFORM_REQ;
@@ -4011,7 +4047,7 @@ replay_again:
 
        cifs_dbg(FYI, "change notify\n");
        if (!ses || !server)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        if (smb3_encryption_required(tcon))
                flags |= CIFS_TRANSFORM_REQ;
@@ -4347,7 +4383,7 @@ replay_again:
 
        cifs_dbg(FYI, "flush\n");
        if (!ses || !(ses->server))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        if (smb3_encryption_required(tcon))
                flags |= CIFS_TRANSFORM_REQ;
@@ -4582,11 +4618,12 @@ do_retry:
                trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_malformed);
                credits.value = le16_to_cpu(shdr->CreditRequest);
                credits.instance = server->reconnect_instance;
-               rdata->result = -EIO;
+               rdata->result = smb_EIO(smb_eio_trace_read_rsp_malformed);
                break;
        default:
                trace_netfs_sreq(&rdata->subreq, netfs_sreq_trace_io_unknown);
-               rdata->result = -EIO;
+               rdata->result = smb_EIO1(smb_eio_trace_read_mid_state_unknown,
+                                        mid->mid_state);
                break;
        }
 #ifdef CONFIG_CIFS_SMB_DIRECT
@@ -4795,7 +4832,8 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
            (*nbytes > io_parms->length)) {
                cifs_dbg(FYI, "bad length %d for count %d\n",
                         *nbytes, io_parms->length);
-               rc = -EIO;
+               rc = smb_EIO2(smb_eio_trace_read_overlarge,
+                             *nbytes, io_parms->length);
                *nbytes = 0;
        }
 
@@ -4881,11 +4919,12 @@ smb2_writev_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid)
                trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_malformed);
                credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
                credits.instance = server->reconnect_instance;
-               result = -EIO;
+               result = smb_EIO(smb_eio_trace_write_rsp_malformed);
                break;
        default:
                trace_netfs_sreq(&wdata->subreq, netfs_sreq_trace_io_unknown);
-               result = -EIO;
+               result = smb_EIO1(smb_eio_trace_write_mid_state_unknown,
+                                 mid->mid_state);
                break;
        }
 #ifdef CONFIG_CIFS_SMB_DIRECT
@@ -5528,7 +5567,7 @@ replay_again:
        server = cifs_pick_channel(ses);
 
        if (!ses || !(ses->server))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        if (smb3_encryption_required(tcon))
                flags |= CIFS_TRANSFORM_REQ;
@@ -5663,7 +5702,7 @@ replay_again:
        server = cifs_pick_channel(ses);
 
        if (!ses || !server)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        if (!num)
                return -EINVAL;
@@ -5860,7 +5899,7 @@ build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
        cifs_dbg(FYI, "Query FSInfo level %d\n", level);
 
        if ((tcon->ses == NULL) || server == NULL)
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
 
        rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server,
                                 (void **) &req, &total_len);
index 99fa48bcd459866be1f52fa3ea690efdd6417cc4..8b9000a831816c8ab432834ff2c55c5372a02ab3 100644 (file)
@@ -153,7 +153,7 @@ static int smb2_get_sign_key(struct TCP_Server_Info *server,
                                memcpy(key, ses->auth_key.response,
                                       SMB2_NTLMV2_SESSKEY_SIZE);
                        } else {
-                               rc = -EIO;
+                               rc = smb_EIO(smb_eio_trace_no_auth_key);
                        }
                        break;
                default:
index 28e00c34df1cbb062b3d28676130f04bff7ac300..252073352e797b26c20adc7f0a296949a7ec8904 100644 (file)
 /*
  * Specify enums for tracing information.
  */
+#define smb_eio_traces \
+       EM(smb_eio_trace_compress_copy,                 "compress_copy") \
+       EM(smb_eio_trace_copychunk_inv_rsp,             "copychunk_inv_rsp") \
+       EM(smb_eio_trace_copychunk_overcopy_b,          "copychunk_overcopy_b") \
+       EM(smb_eio_trace_copychunk_overcopy_c,          "copychunk_overcopy_c") \
+       EM(smb_eio_trace_create_rsp_too_small,          "create_rsp_too_small") \
+       EM(smb_eio_trace_dfsref_no_rsp,                 "dfsref_no_rsp") \
+       EM(smb_eio_trace_ea_overrun,                    "ea_overrun") \
+       EM(smb_eio_trace_extract_will_pin,              "extract_will_pin") \
+       EM(smb_eio_trace_forced_shutdown,               "forced_shutdown") \
+       EM(smb_eio_trace_getacl_bcc_too_small,          "getacl_bcc_too_small") \
+       EM(smb_eio_trace_getcifsacl_param_count,        "getcifsacl_param_count") \
+       EM(smb_eio_trace_getdfsrefer_bcc_too_small,     "getdfsrefer_bcc_too_small") \
+       EM(smb_eio_trace_getextattr_bcc_too_small,      "getextattr_bcc_too_small") \
+       EM(smb_eio_trace_getextattr_inv_size,           "getextattr_inv_size") \
+       EM(smb_eio_trace_getsrvinonum_bcc_too_small,    "getsrvinonum_bcc_too_small") \
+       EM(smb_eio_trace_getsrvinonum_size,             "getsrvinonum_size") \
+       EM(smb_eio_trace_ioctl_data_len,                "ioctl_data_len") \
+       EM(smb_eio_trace_ioctl_no_rsp,                  "ioctl_no_rsp") \
+       EM(smb_eio_trace_ioctl_out_off,                 "ioctl_out_off") \
+       EM(smb_eio_trace_lock_bcc_too_small,            "lock_bcc_too_small") \
+       EM(smb_eio_trace_lock_data_too_small,           "lock_data_too_small") \
+       EM(smb_eio_trace_malformed_ksid_key,            "malformed_ksid_key") \
+       EM(smb_eio_trace_malformed_sid_key,             "malformed_sid_key") \
+       EM(smb_eio_trace_mkdir_no_rsp,                  "mkdir_no_rsp") \
+       EM(smb_eio_trace_neg_bad_rsplen,                "neg_bad_rsplen") \
+       EM(smb_eio_trace_neg_decode_token,              "neg_decode_token") \
+       EM(smb_eio_trace_neg_info_caps,                 "neg_info_caps") \
+       EM(smb_eio_trace_neg_info_dialect,              "neg_info_dialect") \
+       EM(smb_eio_trace_neg_info_fail,                 "neg_info_fail") \
+       EM(smb_eio_trace_neg_info_sec_mode,             "neg_info_sec_mode") \
+       EM(smb_eio_trace_neg_inval_dialect,             "neg_inval_dialect") \
+       EM(smb_eio_trace_neg_no_crypt_key,              "neg_no_crypt_key") \
+       EM(smb_eio_trace_neg_sec_blob_too_small,        "neg_sec_blob_too_small") \
+       EM(smb_eio_trace_neg_unreq_dialect,             "neg_unreq_dialect") \
+       EM(smb_eio_trace_no_auth_key,                   "no_auth_key") \
+       EM(smb_eio_trace_no_lease_key,                  "no_lease_key") \
+       EM(smb_eio_trace_not_netfs_writeback,           "not_netfs_writeback") \
+       EM(smb_eio_trace_null_pointers,                 "null_pointers") \
+       EM(smb_eio_trace_oldqfsinfo_bcc_too_small,      "oldqfsinfo_bcc_too_small") \
+       EM(smb_eio_trace_pend_del_fail,                 "pend_del_fail") \
+       EM(smb_eio_trace_qalleas_bcc_too_small,         "qalleas_bcc_too_small") \
+       EM(smb_eio_trace_qalleas_ea_overlong,           "qalleas_ea_overlong") \
+       EM(smb_eio_trace_qalleas_overlong,              "qalleas_overlong") \
+       EM(smb_eio_trace_qfileinfo_bcc_too_small,       "qfileinfo_bcc_too_small") \
+       EM(smb_eio_trace_qfileinfo_invalid,             "qfileinfo_invalid") \
+       EM(smb_eio_trace_qfsattrinfo_bcc_too_small,     "qfsattrinfo_bcc_too_small") \
+       EM(smb_eio_trace_qfsdevinfo_bcc_too_small,      "qfsdevinfo_bcc_too_small") \
+       EM(smb_eio_trace_qfsinfo_bcc_too_small,         "qfsinfo_bcc_too_small") \
+       EM(smb_eio_trace_qfsposixinfo_bcc_too_small,    "qfsposixinfo_bcc_too_small") \
+       EM(smb_eio_trace_qfsunixinfo_bcc_too_small,     "qfsunixinfo_bcc_too_small") \
+       EM(smb_eio_trace_qpathinfo_bcc_too_small,       "qpathinfo_bcc_too_small") \
+       EM(smb_eio_trace_qpathinfo_invalid,             "qpathinfo_invalid") \
+       EM(smb_eio_trace_qreparse_data_area,            "qreparse_data_area") \
+       EM(smb_eio_trace_qreparse_rep_datalen,          "qreparse_rep_datalen") \
+       EM(smb_eio_trace_qreparse_ret_datalen,          "qreparse_ret_datalen") \
+       EM(smb_eio_trace_qreparse_setup_count,          "qreparse_setup_count") \
+       EM(smb_eio_trace_qreparse_sizes_wrong,          "qreparse_sizes_wrong") \
+       EM(smb_eio_trace_qsym_bcc_too_small,            "qsym_bcc_too_small") \
+       EM(smb_eio_trace_read_mid_state_unknown,        "read_mid_state_unknown") \
+       EM(smb_eio_trace_read_overlarge,                "read_overlarge") \
+       EM(smb_eio_trace_read_rsp_malformed,            "read_rsp_malformed") \
+       EM(smb_eio_trace_read_rsp_short,                "read_rsp_short") \
+       EM(smb_eio_trace_read_too_far,                  "read_too_far") \
+       EM(smb_eio_trace_reparse_data_len,              "reparse_data_len") \
+       EM(smb_eio_trace_reparse_native_len,            "reparse_native_len") \
+       EM(smb_eio_trace_reparse_native_nul,            "reparse_native_nul") \
+       EM(smb_eio_trace_reparse_native_sym_len,        "reparse_native_sym_len") \
+       EM(smb_eio_trace_reparse_nfs_dev,               "reparse_nfs_dev") \
+       EM(smb_eio_trace_reparse_nfs_nul,               "reparse_nfs_nul") \
+       EM(smb_eio_trace_reparse_nfs_sockfifo,          "reparse_nfs_sockfifo") \
+       EM(smb_eio_trace_reparse_nfs_symbuf,            "reparse_nfs_symbuf") \
+       EM(smb_eio_trace_reparse_nfs_too_short,         "reparse_nfs_too_short") \
+       EM(smb_eio_trace_reparse_overlong,              "reparse_overlong") \
+       EM(smb_eio_trace_reparse_rdlen,                 "reparse_rdlen") \
+       EM(smb_eio_trace_reparse_wsl_nul,               "reparse_wsl_nul") \
+       EM(smb_eio_trace_reparse_wsl_symbuf,            "reparse_wsl_symbuf") \
+       EM(smb_eio_trace_reparse_wsl_ver,               "reparse_wsl_ver") \
+       EM(smb_eio_trace_rx_b_read_short,               "rx_b_read_short") \
+       EM(smb_eio_trace_rx_bad_datalen,                "rx_bad_datalen") \
+       EM(smb_eio_trace_rx_both_buf,                   "rx_both_buf") \
+       EM(smb_eio_trace_rx_calc_len_too_big,           "rx_calc_len_too_big") \
+       EM(smb_eio_trace_rx_check_rsp,                  "rx_check_rsp") \
+       EM(smb_eio_trace_rx_copy_to_iter,               "rx_copy_to_iter") \
+       EM(smb_eio_trace_rx_insuff_res,                 "rx_insuff_res") \
+       EM(smb_eio_trace_rx_inv_bcc,                    "rx_inv_bcc") \
+       EM(smb_eio_trace_rx_mid_unready,                "rx_mid_unready") \
+       EM(smb_eio_trace_rx_neg_sess_resp,              "rx_neg_sess_resp") \
+       EM(smb_eio_trace_rx_overlong,                   "rx_overlong") \
+       EM(smb_eio_trace_rx_overpage,                   "rx_overpage") \
+       EM(smb_eio_trace_rx_pos_sess_resp,              "rx_pos_sess_resp") \
+       EM(smb_eio_trace_rx_rfc1002_magic,              "rx_rfc1002_magic") \
+       EM(smb_eio_trace_rx_sync_mid_invalid,           "rx_sync_mid_invalid") \
+       EM(smb_eio_trace_rx_sync_mid_malformed,         "rx_sync_mid_malformed") \
+       EM(smb_eio_trace_rx_too_short,                  "rx_too_short") \
+       EM(smb_eio_trace_rx_trans2_extract,             "rx_trans2_extract") \
+       EM(smb_eio_trace_rx_unknown_resp,               "rx_unknown_resp") \
+       EM(smb_eio_trace_rx_unspec_error,               "rx_unspec_error") \
+       EM(smb_eio_trace_sess_buf_off,                  "sess_buf_off") \
+       EM(smb_eio_trace_sess_exiting,                  "sess_exiting") \
+       EM(smb_eio_trace_sess_krb_wcc,                  "sess_krb_wcc") \
+       EM(smb_eio_trace_sess_nl2_wcc,                  "sess_nl2_wcc") \
+       EM(smb_eio_trace_sess_rawnl_auth_wcc,           "sess_rawnl_auth_wcc") \
+       EM(smb_eio_trace_sess_rawnl_neg_wcc,            "sess_rawnl_neg_wcc") \
+       EM(smb_eio_trace_short_symlink_write,           "short_symlink_write") \
+       EM(smb_eio_trace_sid_too_many_auth,             "sid_too_many_auth") \
+       EM(smb_eio_trace_sig_data_too_small,            "sig_data_too_small") \
+       EM(smb_eio_trace_sig_iter,                      "sig_iter") \
+       EM(smb_eio_trace_smb1_received_error,           "smb1_received_error") \
+       EM(smb_eio_trace_smb2_received_error,           "smb2_received_error") \
+       EM(smb_eio_trace_sym_slash,                     "sym_slash") \
+       EM(smb_eio_trace_sym_target_len,                "sym_target_len") \
+       EM(smb_eio_trace_symlink_file_size,             "symlink_file_size") \
+       EM(smb_eio_trace_tdis_in_reconnect,             "tdis_in_reconnect") \
+       EM(smb_eio_trace_tx_chained_async,              "tx_chained_async") \
+       EM(smb_eio_trace_tx_compress_failed,            "tx_compress_failed") \
+       EM(smb_eio_trace_tx_copy_iter_to_buf,           "tx_copy_iter_to_buf") \
+       EM(smb_eio_trace_tx_copy_to_buf,                "tx_copy_to_buf") \
+       EM(smb_eio_trace_tx_max_compound,               "tx_max_compound") \
+       EM(smb_eio_trace_tx_miscopy_to_buf,             "tx_miscopy_to_buf") \
+       EM(smb_eio_trace_tx_need_transform,             "tx_need_transform") \
+       EM(smb_eio_trace_tx_too_long,                   "sr_too_long") \
+       EM(smb_eio_trace_unixqfileinfo_bcc_too_small,   "unixqfileinfo_bcc_too_small") \
+       EM(smb_eio_trace_unixqpathinfo_bcc_too_small,   "unixqpathinfo_bcc_too_small") \
+       EM(smb_eio_trace_user_iter,                     "user_iter") \
+       EM(smb_eio_trace_write_bad_buf_type,            "write_bad_buf_type") \
+       EM(smb_eio_trace_write_mid_state_unknown,       "write_mid_state_unknown") \
+       EM(smb_eio_trace_write_rsp_malformed,           "write_rsp_malformed") \
+       E_(smb_eio_trace_write_too_far,                 "write_too_far")
+
 #define smb3_rw_credits_traces \
        EM(cifs_trace_rw_credits_call_readv_adjust,     "rd-call-adj") \
        EM(cifs_trace_rw_credits_call_writev_adjust,    "wr-call-adj") \
 #define EM(a, b) a,
 #define E_(a, b) a
 
+enum smb_eio_trace             { smb_eio_traces } __mode(byte);
 enum smb3_rw_credits_trace     { smb3_rw_credits_traces } __mode(byte);
 enum smb3_tcon_ref_trace       { smb3_tcon_ref_traces } __mode(byte);
 
@@ -92,6 +223,7 @@ enum smb3_tcon_ref_trace     { smb3_tcon_ref_traces } __mode(byte);
 #define EM(a, b) TRACE_DEFINE_ENUM(a);
 #define E_(a, b) TRACE_DEFINE_ENUM(a);
 
+smb_eio_traces;
 smb3_rw_credits_traces;
 smb3_tcon_ref_traces;
 
@@ -1616,6 +1748,23 @@ TRACE_EVENT(smb3_rw_credits,
                      __entry->server_credits, __entry->in_flight)
            );
 
+TRACE_EVENT(smb3_eio,
+           TP_PROTO(enum smb_eio_trace trace, unsigned long info, unsigned long info2),
+           TP_ARGS(trace, info, info2),
+           TP_STRUCT__entry(
+                   __field(enum smb_eio_trace, trace)
+                   __field(unsigned long,      info)
+                   __field(unsigned long,      info2)
+                            ),
+           TP_fast_assign(
+                   __entry->trace      = trace;
+                   __entry->info       = info;
+                   __entry->info2      = info2;
+                          ),
+           TP_printk("%s info=%lx,%lx",
+                     __print_symbolic(__entry->trace, smb_eio_traces),
+                     __entry->info, __entry->info2)
+           );
 
 #undef EM
 #undef E_
index 1b632ea110e78028a2726c39a22e2e83e47e6d18..3b34c3f4da2df786d2c3f170a3648ac324eed213 100644 (file)
@@ -402,11 +402,11 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
                return __smb_send_rqst(server, num_rqst, rqst);
 
        if (WARN_ON_ONCE(num_rqst > MAX_COMPOUND - 1))
-               return -EIO;
+               return smb_EIO1(smb_eio_trace_tx_max_compound, num_rqst);
 
        if (!server->ops->init_transform_rq) {
                cifs_server_dbg(VFS, "Encryption requested but transform callback is missing\n");
-               return -EIO;
+               return smb_EIO(smb_eio_trace_tx_need_transform);
        }
 
        new_rqst[0].rq_iov = &iov;
@@ -753,7 +753,7 @@ int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server
                rc = -EAGAIN;
                break;
        case MID_RESPONSE_MALFORMED:
-               rc = -EIO;
+               rc = smb_EIO(smb_eio_trace_rx_sync_mid_malformed);
                break;
        case MID_SHUTDOWN:
                rc = -EHOSTDOWN;
@@ -769,7 +769,7 @@ int cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server
                spin_unlock(&server->mid_queue_lock);
                cifs_server_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n",
                         __func__, mid->mid, mid->mid_state);
-               rc = -EIO;
+               rc = smb_EIO1(smb_eio_trace_rx_sync_mid_invalid, mid->mid_state);
                goto sync_mid_done;
        }
        spin_unlock(&server->mid_queue_lock);
@@ -883,7 +883,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 
        if (!ses || !ses->server || !server) {
                cifs_dbg(VFS, "Null session\n");
-               return -EIO;
+               return smb_EIO(smb_eio_trace_null_pointers);
        }
 
        spin_lock(&server->srv_lock);
@@ -1043,7 +1043,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
 
                if (!mid[i]->resp_buf ||
                    mid[i]->mid_state != MID_RESPONSE_READY) {
-                       rc = -EIO;
+                       rc = smb_EIO1(smb_eio_trace_rx_mid_unready, mid[i]->mid_state);
                        cifs_dbg(FYI, "Bad MID state?\n");
                        goto out;
                }
@@ -1215,7 +1215,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
                cifs_dbg(FYI, "%s: server returned short header. got=%u expected=%zu\n",
                         __func__, server->total_read,
                         server->vals->read_rsp_size);
-               rdata->result = -EIO;
+               rdata->result = smb_EIO2(smb_eio_trace_read_rsp_short,
+                                        server->total_read, server->vals->read_rsp_size);
                return cifs_readv_discard(server, mid);
        }
 
@@ -1233,7 +1234,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
                /* data_offset is beyond the end of smallbuf */
                cifs_dbg(FYI, "%s: data offset (%u) beyond end of smallbuf\n",
                         __func__, data_offset);
-               rdata->result = -EIO;
+               rdata->result = smb_EIO1(smb_eio_trace_read_overlarge,
+                                        data_offset);
                return cifs_readv_discard(server, mid);
        }
 
@@ -1258,7 +1260,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
        data_len = server->ops->read_data_length(buf, use_rdma_mr);
        if (!use_rdma_mr && (data_offset + data_len > buflen)) {
                /* data_len is corrupt -- discard frame */
-               rdata->result = -EIO;
+               rdata->result = smb_EIO2(smb_eio_trace_read_rsp_malformed,
+                                        data_offset + data_len, buflen);
                return cifs_readv_discard(server, mid);
        }
 
index 029910d56c22e5827f4fb49e65755276ac067354..6bc89c59164ad0c70e128569850d7198357d3147 100644 (file)
@@ -397,7 +397,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
        void *page;
 
        if (unlikely(cifs_forced_shutdown(cifs_sb)))
-               return -EIO;
+               return smb_EIO(smb_eio_trace_forced_shutdown);
 
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
                return -EOPNOTSUPP;