aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c59
1 files changed, 38 insertions, 21 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 78db68a5cf44..94b7788c3189 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1653,24 +1653,26 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1653 * If yes, we have encountered a double deliminator 1653 * If yes, we have encountered a double deliminator
1654 * reset the NULL character to the deliminator 1654 * reset the NULL character to the deliminator
1655 */ 1655 */
1656 if (tmp_end < end && tmp_end[1] == delim) 1656 if (tmp_end < end && tmp_end[1] == delim) {
1657 tmp_end[0] = delim; 1657 tmp_end[0] = delim;
1658 1658
1659 /* Keep iterating until we get to a single deliminator 1659 /* Keep iterating until we get to a single
1660 * OR the end 1660 * deliminator OR the end
1661 */ 1661 */
1662 while ((tmp_end = strchr(tmp_end, delim)) != NULL && 1662 while ((tmp_end = strchr(tmp_end, delim))
1663 (tmp_end[1] == delim)) { 1663 != NULL && (tmp_end[1] == delim)) {
1664 tmp_end = (char *) &tmp_end[2]; 1664 tmp_end = (char *) &tmp_end[2];
1665 } 1665 }
1666 1666
1667 /* Reset var options to point to next element */ 1667 /* Reset var options to point to next element */
1668 if (tmp_end) { 1668 if (tmp_end) {
1669 tmp_end[0] = '\0'; 1669 tmp_end[0] = '\0';
1670 options = (char *) &tmp_end[1]; 1670 options = (char *) &tmp_end[1];
1671 } else 1671 } else
1672 /* Reached the end of the mount option string */ 1672 /* Reached the end of the mount option
1673 options = end; 1673 * string */
1674 options = end;
1675 }
1674 1676
1675 /* Now build new password string */ 1677 /* Now build new password string */
1676 temp_len = strlen(value); 1678 temp_len = strlen(value);
@@ -3443,6 +3445,18 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
3443#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) 3445#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
3444#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) 3446#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
3445 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
3446static unsigned int 3460static unsigned int
3447cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) 3461cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
3448{ 3462{
@@ -3473,6 +3487,9 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
3473 wsize = min_t(unsigned int, wsize, 3487 wsize = min_t(unsigned int, wsize,
3474 server->maxBuf - sizeof(WRITE_REQ) + 4); 3488 server->maxBuf - sizeof(WRITE_REQ) + 4);
3475 3489
3490 /* limit to the amount that we can kmap at once */
3491 wsize = min_t(unsigned int, wsize, CIFS_KMAP_SIZE_LIMIT);
3492
3476 /* hard limit of CIFS_MAX_WSIZE */ 3493 /* hard limit of CIFS_MAX_WSIZE */
3477 wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); 3494 wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
3478 3495
@@ -3493,18 +3510,15 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
3493 * 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
3494 * bufsize for reads, testing against win98se shows that it throws 3511 * bufsize for reads, testing against win98se shows that it throws
3495 * 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.
3496 * 3514 *
3497 * 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
3498 * 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.
3499 *
3500 * FIXME: Is there a better heuristic for this?
3501 */ 3517 */
3502 if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP)) 3518 if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP))
3503 defsize = CIFS_DEFAULT_IOSIZE; 3519 defsize = CIFS_DEFAULT_IOSIZE;
3504 else if (server->capabilities & CAP_LARGE_READ_X) 3520 else if (server->capabilities & CAP_LARGE_READ_X)
3505 defsize = CIFS_DEFAULT_NON_POSIX_RSIZE; 3521 defsize = CIFS_DEFAULT_NON_POSIX_RSIZE;
3506 else if (server->maxBuf >= PAGE_CACHE_SIZE)
3507 defsize = CIFSMaxBufSize;
3508 else 3522 else
3509 defsize = server->maxBuf - sizeof(READ_RSP); 3523 defsize = server->maxBuf - sizeof(READ_RSP);
3510 3524
@@ -3517,6 +3531,9 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
3517 if (!(server->capabilities & CAP_LARGE_READ_X)) 3531 if (!(server->capabilities & CAP_LARGE_READ_X))
3518 rsize = min_t(unsigned int, CIFSMaxBufSize, rsize); 3532 rsize = min_t(unsigned int, CIFSMaxBufSize, rsize);
3519 3533
3534 /* limit to the amount that we can kmap at once */
3535 rsize = min_t(unsigned int, rsize, CIFS_KMAP_SIZE_LIMIT);
3536
3520 /* hard limit of CIFS_MAX_RSIZE */ 3537 /* hard limit of CIFS_MAX_RSIZE */
3521 rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE); 3538 rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE);
3522 3539