diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 67 |
1 files changed, 43 insertions, 24 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index ccafdedd0dbc..94b7788c3189 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1058,13 +1058,15 @@ cifs_demultiplex_thread(void *p) | |||
1058 | if (mid_entry != NULL) { | 1058 | if (mid_entry != NULL) { |
1059 | if (!mid_entry->multiRsp || mid_entry->multiEnd) | 1059 | if (!mid_entry->multiRsp || mid_entry->multiEnd) |
1060 | mid_entry->callback(mid_entry); | 1060 | mid_entry->callback(mid_entry); |
1061 | } else if (!server->ops->is_oplock_break(buf, server)) { | 1061 | } else if (!server->ops->is_oplock_break || |
1062 | !server->ops->is_oplock_break(buf, server)) { | ||
1062 | cERROR(1, "No task to wake, unknown frame received! " | 1063 | cERROR(1, "No task to wake, unknown frame received! " |
1063 | "NumMids %d", atomic_read(&midCount)); | 1064 | "NumMids %d", atomic_read(&midCount)); |
1064 | cifs_dump_mem("Received Data is: ", buf, | 1065 | cifs_dump_mem("Received Data is: ", buf, |
1065 | HEADER_SIZE(server)); | 1066 | HEADER_SIZE(server)); |
1066 | #ifdef CONFIG_CIFS_DEBUG2 | 1067 | #ifdef CONFIG_CIFS_DEBUG2 |
1067 | server->ops->dump_detail(buf); | 1068 | if (server->ops->dump_detail) |
1069 | server->ops->dump_detail(buf); | ||
1068 | cifs_dump_mids(server); | 1070 | cifs_dump_mids(server); |
1069 | #endif /* CIFS_DEBUG2 */ | 1071 | #endif /* CIFS_DEBUG2 */ |
1070 | 1072 | ||
@@ -1651,24 +1653,26 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
1651 | * If yes, we have encountered a double deliminator | 1653 | * If yes, we have encountered a double deliminator |
1652 | * reset the NULL character to the deliminator | 1654 | * reset the NULL character to the deliminator |
1653 | */ | 1655 | */ |
1654 | if (tmp_end < end && tmp_end[1] == delim) | 1656 | if (tmp_end < end && tmp_end[1] == delim) { |
1655 | tmp_end[0] = delim; | 1657 | tmp_end[0] = delim; |
1656 | 1658 | ||
1657 | /* Keep iterating until we get to a single deliminator | 1659 | /* Keep iterating until we get to a single |
1658 | * OR the end | 1660 | * deliminator OR the end |
1659 | */ | 1661 | */ |
1660 | while ((tmp_end = strchr(tmp_end, delim)) != NULL && | 1662 | while ((tmp_end = strchr(tmp_end, delim)) |
1661 | (tmp_end[1] == delim)) { | 1663 | != NULL && (tmp_end[1] == delim)) { |
1662 | tmp_end = (char *) &tmp_end[2]; | 1664 | tmp_end = (char *) &tmp_end[2]; |
1663 | } | 1665 | } |
1664 | 1666 | ||
1665 | /* Reset var options to point to next element */ | 1667 | /* Reset var options to point to next element */ |
1666 | if (tmp_end) { | 1668 | if (tmp_end) { |
1667 | tmp_end[0] = '\0'; | 1669 | tmp_end[0] = '\0'; |
1668 | options = (char *) &tmp_end[1]; | 1670 | options = (char *) &tmp_end[1]; |
1669 | } else | 1671 | } else |
1670 | /* Reached the end of the mount option string */ | 1672 | /* Reached the end of the mount option |
1671 | options = end; | 1673 | * string */ |
1674 | options = end; | ||
1675 | } | ||
1672 | 1676 | ||
1673 | /* Now build new password string */ | 1677 | /* Now build new password string */ |
1674 | temp_len = strlen(value); | 1678 | temp_len = strlen(value); |
@@ -3441,6 +3445,18 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | |||
3441 | #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) | 3445 | #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) |
3442 | #define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) | 3446 | #define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) |
3443 | 3447 | ||
3448 | /* | ||
3449 | * On hosts with high memory, we can't currently support wsize/rsize that are | ||
3450 | * larger than we can kmap at once. Cap the rsize/wsize at | ||
3451 | * LAST_PKMAP * PAGE_SIZE. We'll never be able to fill a read or write request | ||
3452 | * larger than that anyway. | ||
3453 | */ | ||
3454 | #ifdef CONFIG_HIGHMEM | ||
3455 | #define CIFS_KMAP_SIZE_LIMIT (LAST_PKMAP * PAGE_CACHE_SIZE) | ||
3456 | #else /* CONFIG_HIGHMEM */ | ||
3457 | #define CIFS_KMAP_SIZE_LIMIT (1<<24) | ||
3458 | #endif /* CONFIG_HIGHMEM */ | ||
3459 | |||
3444 | static unsigned int | 3460 | static unsigned int |
3445 | cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | 3461 | cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) |
3446 | { | 3462 | { |
@@ -3471,6 +3487,9 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | |||
3471 | wsize = min_t(unsigned int, wsize, | 3487 | wsize = min_t(unsigned int, wsize, |
3472 | server->maxBuf - sizeof(WRITE_REQ) + 4); | 3488 | server->maxBuf - sizeof(WRITE_REQ) + 4); |
3473 | 3489 | ||
3490 | /* limit to the amount that we can kmap at once */ | ||
3491 | wsize = min_t(unsigned int, wsize, CIFS_KMAP_SIZE_LIMIT); | ||
3492 | |||
3474 | /* hard limit of CIFS_MAX_WSIZE */ | 3493 | /* hard limit of CIFS_MAX_WSIZE */ |
3475 | wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); | 3494 | wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); |
3476 | 3495 | ||
@@ -3491,18 +3510,15 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | |||
3491 | * MS-CIFS indicates that servers are only limited by the client's | 3510 | * MS-CIFS indicates that servers are only limited by the client's |
3492 | * bufsize for reads, testing against win98se shows that it throws | 3511 | * bufsize for reads, testing against win98se shows that it throws |
3493 | * INVALID_PARAMETER errors if you try to request too large a read. | 3512 | * INVALID_PARAMETER errors if you try to request too large a read. |
3513 | * OS/2 just sends back short reads. | ||
3494 | * | 3514 | * |
3495 | * If the server advertises a MaxBufferSize of less than one page, | 3515 | * If the server doesn't advertise CAP_LARGE_READ_X, then assume that |
3496 | * assume that it also can't satisfy reads larger than that either. | 3516 | * it can't handle a read request larger than its MaxBufferSize either. |
3497 | * | ||
3498 | * FIXME: Is there a better heuristic for this? | ||
3499 | */ | 3517 | */ |
3500 | if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP)) | 3518 | if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP)) |
3501 | defsize = CIFS_DEFAULT_IOSIZE; | 3519 | defsize = CIFS_DEFAULT_IOSIZE; |
3502 | else if (server->capabilities & CAP_LARGE_READ_X) | 3520 | else if (server->capabilities & CAP_LARGE_READ_X) |
3503 | defsize = CIFS_DEFAULT_NON_POSIX_RSIZE; | 3521 | defsize = CIFS_DEFAULT_NON_POSIX_RSIZE; |
3504 | else if (server->maxBuf >= PAGE_CACHE_SIZE) | ||
3505 | defsize = CIFSMaxBufSize; | ||
3506 | else | 3522 | else |
3507 | defsize = server->maxBuf - sizeof(READ_RSP); | 3523 | defsize = server->maxBuf - sizeof(READ_RSP); |
3508 | 3524 | ||
@@ -3515,6 +3531,9 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) | |||
3515 | if (!(server->capabilities & CAP_LARGE_READ_X)) | 3531 | if (!(server->capabilities & CAP_LARGE_READ_X)) |
3516 | rsize = min_t(unsigned int, CIFSMaxBufSize, rsize); | 3532 | rsize = min_t(unsigned int, CIFSMaxBufSize, rsize); |
3517 | 3533 | ||
3534 | /* limit to the amount that we can kmap at once */ | ||
3535 | rsize = min_t(unsigned int, rsize, CIFS_KMAP_SIZE_LIMIT); | ||
3536 | |||
3518 | /* hard limit of CIFS_MAX_RSIZE */ | 3537 | /* hard limit of CIFS_MAX_RSIZE */ |
3519 | rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE); | 3538 | rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE); |
3520 | 3539 | ||
@@ -3938,7 +3957,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, | |||
3938 | header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, | 3957 | header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, |
3939 | NULL /*no tid */ , 4 /*wct */ ); | 3958 | NULL /*no tid */ , 4 /*wct */ ); |
3940 | 3959 | ||
3941 | smb_buffer->Mid = GetNextMid(ses->server); | 3960 | smb_buffer->Mid = get_next_mid(ses->server); |
3942 | smb_buffer->Uid = ses->Suid; | 3961 | smb_buffer->Uid = ses->Suid; |
3943 | pSMB = (TCONX_REQ *) smb_buffer; | 3962 | pSMB = (TCONX_REQ *) smb_buffer; |
3944 | pSMBr = (TCONX_RSP *) smb_buffer_response; | 3963 | pSMBr = (TCONX_RSP *) smb_buffer_response; |