Commit ec01d738 authored by Jeff Layton's avatar Jeff Layton Committed by Steven French

cifs: when server doesn't set CAP_LARGE_READ_X, cap default rsize at MaxBufferSize

When the server doesn't advertise CAP_LARGE_READ_X, then MS-CIFS states
that you must cap the size of the read at the client's MaxBufferSize.
Unfortunately, testing with many older servers shows that they often
can't service a read larger than their own MaxBufferSize.

Since we can't assume what the server will do in this situation, we must
be conservative here for the default. When the server can't do large
reads, then assume that it can't satisfy any read larger than its
MaxBufferSize either.

Luckily almost all modern servers can do large reads, so this won't
affect them. This is really just for older win9x and OS/2 era servers.
Also, note that this patch just governs the default rsize. The admin can
always override this if he so chooses.

Cc: <stable@vger.kernel.org> # 3.2
Reported-by: default avatarDavid H. Durgee <dhdurgee@acm.org>
Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteven French <sfrench@w500smf.(none)>
parent e73f843a
...@@ -3495,18 +3495,15 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) ...@@ -3495,18 +3495,15 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
* MS-CIFS indicates that servers are only limited by the client's * MS-CIFS indicates that servers are only limited by the client's
* bufsize for reads, testing against win98se shows that it throws * bufsize for reads, testing against win98se shows that it throws
* INVALID_PARAMETER errors if you try to request too large a read. * INVALID_PARAMETER errors if you try to request too large a read.
* OS/2 just sends back short reads.
* *
* If the server advertises a MaxBufferSize of less than one page, * If the server doesn't advertise CAP_LARGE_READ_X, then assume that
* assume that it also can't satisfy reads larger than that either. * it can't handle a read request larger than its MaxBufferSize either.
*
* FIXME: Is there a better heuristic for this?
*/ */
if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP)) if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP))
defsize = CIFS_DEFAULT_IOSIZE; defsize = CIFS_DEFAULT_IOSIZE;
else if (server->capabilities & CAP_LARGE_READ_X) else if (server->capabilities & CAP_LARGE_READ_X)
defsize = CIFS_DEFAULT_NON_POSIX_RSIZE; defsize = CIFS_DEFAULT_NON_POSIX_RSIZE;
else if (server->maxBuf >= PAGE_CACHE_SIZE)
defsize = CIFSMaxBufSize;
else else
defsize = server->maxBuf - sizeof(READ_RSP); defsize = server->maxBuf - sizeof(READ_RSP);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment