mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 18:53:52 +08:00
two fixes for stable for guest mount problems with smb3.1.1, two fixes for crediting on resent requests, a byte range lock leak fix and fixes for two incorrect rc mappings
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAlyWPM0ACgkQiiy9cAdy T1FKCAwAsrZ2WlTdSp5/1Ogwa18vrS5dMHnMipOaZytG6HxBDXPGDzohNQxHbLQK ShxQIrcPoVmB6WVrzpEYrPGamDETogp+ennVHwngTNDP7TN/U/oSVzBSJ/ZW32uO w6LSXm3upVNluQLalLhy95xRUhZrt/FkCGp8BkTduR9VObfDtSHouCvsdMl0gXL1 qHZM1LguJsB0ziWNQpeXvFar63NO5bJEBtvP+sc+sGjuoRskE6Bz68GCg3t+Mbp+ 73M/iVil8HWMHZELs1JwPslakbp1xDAcz7fjcizrVXcMaW8xqT68rylORC4aY3p3 bNqDTCPRjufE0ktjSi8ld8g9W3W/TbyizBVUDUHYqDzRomx5sx74vz57yCdqyKZX /MENHMcrQ8OcB1OXKKTtgbh3dEcwSbrKHKuO+0XMz4We1S5Py8qRRTVxissqxWx6 aSeXYDC2XLlsPO9/OY6h08pQ21i7qO8wbuCbmpunaMgnk1vurF0B5Xt8s27FSoEK M32p50xP =Q90v -----END PGP SIGNATURE----- Merge tag '5.1-rc1-cifs-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull smb3 fixes from Steve French: - two fixes for stable for guest mount problems with smb3.1.1 - two fixes for crediting (SMB3 flow control) on resent requests - a byte range lock leak fix - two fixes for incorrect rc mappings * tag '5.1-rc1-cifs-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: update internal module version number SMB3: Fix SMB3.1.1 guest mounts to Samba cifs: Fix slab-out-of-bounds when tracing SMB tcon cifs: allow guest mounts to work for smb3.11 fix incorrect error code mapping for OBJECTID_NOT_FOUND cifs: fix that return -EINVAL when do dedupe operation CIFS: Fix an issue with re-sending rdata when transport returning -EAGAIN CIFS: Fix an issue with re-sending wdata when transport returning -EAGAIN
This commit is contained in:
commit
38104c0020
@ -1008,7 +1008,7 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
|
||||
unsigned int xid;
|
||||
int rc;
|
||||
|
||||
if (remap_flags & ~REMAP_FILE_ADVISORY)
|
||||
if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
|
||||
return -EINVAL;
|
||||
|
||||
cifs_dbg(FYI, "clone range\n");
|
||||
|
@ -150,5 +150,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
|
||||
extern const struct export_operations cifs_export_ops;
|
||||
#endif /* CONFIG_CIFS_NFSD_EXPORT */
|
||||
|
||||
#define CIFS_VERSION "2.18"
|
||||
#define CIFS_VERSION "2.19"
|
||||
#endif /* _CIFSFS_H */
|
||||
|
152
fs/cifs/file.c
152
fs/cifs/file.c
@ -2632,43 +2632,56 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
|
||||
struct TCP_Server_Info *server =
|
||||
tlink_tcon(wdata->cfile->tlink)->ses->server;
|
||||
|
||||
/*
|
||||
* Wait for credits to resend this wdata.
|
||||
* Note: we are attempting to resend the whole wdata not in segments
|
||||
*/
|
||||
do {
|
||||
rc = server->ops->wait_mtu_credits(server, wdata->bytes, &wsize,
|
||||
&credits);
|
||||
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
if (wsize < wdata->bytes) {
|
||||
add_credits_and_wake_if(server, &credits, 0);
|
||||
msleep(1000);
|
||||
}
|
||||
} while (wsize < wdata->bytes);
|
||||
|
||||
wdata->credits = credits;
|
||||
rc = -EAGAIN;
|
||||
while (rc == -EAGAIN) {
|
||||
rc = 0;
|
||||
if (wdata->cfile->invalidHandle)
|
||||
if (wdata->cfile->invalidHandle) {
|
||||
rc = cifs_reopen_file(wdata->cfile, false);
|
||||
if (!rc)
|
||||
rc = server->ops->async_writev(wdata,
|
||||
if (rc == -EAGAIN)
|
||||
continue;
|
||||
else if (rc)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wait for credits to resend this wdata.
|
||||
* Note: we are attempting to resend the whole wdata not in
|
||||
* segments
|
||||
*/
|
||||
do {
|
||||
rc = server->ops->wait_mtu_credits(server, wdata->bytes,
|
||||
&wsize, &credits);
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
||||
if (wsize < wdata->bytes) {
|
||||
add_credits_and_wake_if(server, &credits, 0);
|
||||
msleep(1000);
|
||||
}
|
||||
} while (wsize < wdata->bytes);
|
||||
wdata->credits = credits;
|
||||
|
||||
rc = adjust_credits(server, &wdata->credits, wdata->bytes);
|
||||
|
||||
if (!rc) {
|
||||
if (wdata->cfile->invalidHandle)
|
||||
rc = -EAGAIN;
|
||||
else
|
||||
rc = server->ops->async_writev(wdata,
|
||||
cifs_uncached_writedata_release);
|
||||
}
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
list_add_tail(&wdata->list, wdata_list);
|
||||
return 0;
|
||||
}
|
||||
/* If the write was successfully sent, we are done */
|
||||
if (!rc) {
|
||||
list_add_tail(&wdata->list, wdata_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
add_credits_and_wake_if(server, &wdata->credits, 0);
|
||||
out:
|
||||
/* Roll back credits and retry if needed */
|
||||
add_credits_and_wake_if(server, &wdata->credits, 0);
|
||||
} while (rc == -EAGAIN);
|
||||
|
||||
fail:
|
||||
kref_put(&wdata->refcount, cifs_uncached_writedata_release);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -2896,12 +2909,12 @@ restart_loop:
|
||||
wdata->bytes, &tmp_from,
|
||||
ctx->cfile, cifs_sb, &tmp_list,
|
||||
ctx);
|
||||
|
||||
kref_put(&wdata->refcount,
|
||||
cifs_uncached_writedata_release);
|
||||
}
|
||||
|
||||
list_splice(&tmp_list, &ctx->list);
|
||||
|
||||
kref_put(&wdata->refcount,
|
||||
cifs_uncached_writedata_release);
|
||||
goto restart_loop;
|
||||
}
|
||||
}
|
||||
@ -3348,44 +3361,55 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
|
||||
struct TCP_Server_Info *server =
|
||||
tlink_tcon(rdata->cfile->tlink)->ses->server;
|
||||
|
||||
/*
|
||||
* Wait for credits to resend this rdata.
|
||||
* Note: we are attempting to resend the whole rdata not in segments
|
||||
*/
|
||||
do {
|
||||
rc = server->ops->wait_mtu_credits(server, rdata->bytes,
|
||||
if (rdata->cfile->invalidHandle) {
|
||||
rc = cifs_reopen_file(rdata->cfile, true);
|
||||
if (rc == -EAGAIN)
|
||||
continue;
|
||||
else if (rc)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for credits to resend this rdata.
|
||||
* Note: we are attempting to resend the whole rdata not in
|
||||
* segments
|
||||
*/
|
||||
do {
|
||||
rc = server->ops->wait_mtu_credits(server, rdata->bytes,
|
||||
&rsize, &credits);
|
||||
|
||||
if (rc)
|
||||
goto out;
|
||||
if (rc)
|
||||
goto fail;
|
||||
|
||||
if (rsize < rdata->bytes) {
|
||||
add_credits_and_wake_if(server, &credits, 0);
|
||||
msleep(1000);
|
||||
if (rsize < rdata->bytes) {
|
||||
add_credits_and_wake_if(server, &credits, 0);
|
||||
msleep(1000);
|
||||
}
|
||||
} while (rsize < rdata->bytes);
|
||||
rdata->credits = credits;
|
||||
|
||||
rc = adjust_credits(server, &rdata->credits, rdata->bytes);
|
||||
if (!rc) {
|
||||
if (rdata->cfile->invalidHandle)
|
||||
rc = -EAGAIN;
|
||||
else
|
||||
rc = server->ops->async_readv(rdata);
|
||||
}
|
||||
} while (rsize < rdata->bytes);
|
||||
|
||||
rdata->credits = credits;
|
||||
rc = -EAGAIN;
|
||||
while (rc == -EAGAIN) {
|
||||
rc = 0;
|
||||
if (rdata->cfile->invalidHandle)
|
||||
rc = cifs_reopen_file(rdata->cfile, true);
|
||||
if (!rc)
|
||||
rc = server->ops->async_readv(rdata);
|
||||
}
|
||||
/* If the read was successfully sent, we are done */
|
||||
if (!rc) {
|
||||
/* Add to aio pending list */
|
||||
list_add_tail(&rdata->list, rdata_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
/* Add to aio pending list */
|
||||
list_add_tail(&rdata->list, rdata_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
add_credits_and_wake_if(server, &rdata->credits, 0);
|
||||
out:
|
||||
kref_put(&rdata->refcount,
|
||||
cifs_uncached_readdata_release);
|
||||
/* Roll back credits and retry if needed */
|
||||
add_credits_and_wake_if(server, &rdata->credits, 0);
|
||||
} while (rc == -EAGAIN);
|
||||
|
||||
fail:
|
||||
kref_put(&rdata->refcount, cifs_uncached_readdata_release);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1036,7 +1036,8 @@ static const struct status_to_posix_error smb2_error_map_table[] = {
|
||||
{STATUS_UNFINISHED_CONTEXT_DELETED, -EIO,
|
||||
"STATUS_UNFINISHED_CONTEXT_DELETED"},
|
||||
{STATUS_NO_TGT_REPLY, -EIO, "STATUS_NO_TGT_REPLY"},
|
||||
{STATUS_OBJECTID_NOT_FOUND, -EIO, "STATUS_OBJECTID_NOT_FOUND"},
|
||||
/* Note that ENOATTTR and ENODATA are the same errno */
|
||||
{STATUS_OBJECTID_NOT_FOUND, -ENODATA, "STATUS_OBJECTID_NOT_FOUND"},
|
||||
{STATUS_NO_IP_ADDRESSES, -EIO, "STATUS_NO_IP_ADDRESSES"},
|
||||
{STATUS_WRONG_CREDENTIAL_HANDLE, -EIO,
|
||||
"STATUS_WRONG_CREDENTIAL_HANDLE"},
|
||||
|
@ -1628,9 +1628,16 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
|
||||
iov[1].iov_base = unc_path;
|
||||
iov[1].iov_len = unc_path_len;
|
||||
|
||||
/* 3.11 tcon req must be signed if not encrypted. See MS-SMB2 3.2.4.1.1 */
|
||||
/*
|
||||
* 3.11 tcon req must be signed if not encrypted. See MS-SMB2 3.2.4.1.1
|
||||
* unless it is guest or anonymous user. See MS-SMB2 3.2.5.3.1
|
||||
* (Samba servers don't always set the flag so also check if null user)
|
||||
*/
|
||||
if ((ses->server->dialect == SMB311_PROT_ID) &&
|
||||
!smb3_encryption_required(tcon))
|
||||
!smb3_encryption_required(tcon) &&
|
||||
!(ses->session_flags &
|
||||
(SMB2_SESSION_FLAG_IS_GUEST|SMB2_SESSION_FLAG_IS_NULL)) &&
|
||||
((ses->user_name != NULL) || (ses->sectype == Kerberos)))
|
||||
req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
|
||||
|
||||
memset(&rqst, 0, sizeof(struct smb_rqst));
|
||||
|
@ -549,19 +549,19 @@ DECLARE_EVENT_CLASS(smb3_tcon_class,
|
||||
__field(unsigned int, xid)
|
||||
__field(__u32, tid)
|
||||
__field(__u64, sesid)
|
||||
__field(const char *, unc_name)
|
||||
__string(name, unc_name)
|
||||
__field(int, rc)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->xid = xid;
|
||||
__entry->tid = tid;
|
||||
__entry->sesid = sesid;
|
||||
__entry->unc_name = unc_name;
|
||||
__assign_str(name, unc_name);
|
||||
__entry->rc = rc;
|
||||
),
|
||||
TP_printk("xid=%u sid=0x%llx tid=0x%x unc_name=%s rc=%d",
|
||||
__entry->xid, __entry->sesid, __entry->tid,
|
||||
__entry->unc_name, __entry->rc)
|
||||
__get_str(name), __entry->rc)
|
||||
)
|
||||
|
||||
#define DEFINE_SMB3_TCON_EVENT(name) \
|
||||
|
Loading…
Reference in New Issue
Block a user