merged On Wed, Jun 22, 2011 at 4:33 PM, Jeff Layton <jlayton@xxxxxxxxxx> wrote: > Hopefully last version. Base signing check on CAP_UNIX instead of > tcon->unix_ext, also clean up the comments a bit more. > > According to Hongwei Sun's blog posting here: > > http://blogs.msdn.com/b/openspecification/archive/2009/04/10/smb-maximum-transmit-buffer-size-and-performance-tuning.aspx > > CAP_LARGE_WRITEX is ignored when signing is active. Also, the maximum > size for a write without CAP_LARGE_WRITEX should be the maxBuf that > the server sent in the NEGOTIATE request. > > Fix the wsize negotiation to take this into account. While we're at it, > alter the other wsize definitions to use sizeof(WRITE_REQ) to allow for > slightly larger amounts of data to potentially be written per request. > > Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> > --- > fs/cifs/connect.c | 33 ++++++++++++++++++++------------- > 1 files changed, 20 insertions(+), 13 deletions(-) > > diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c > index b15b5b0..c8cb83e 100644 > --- a/fs/cifs/connect.c > +++ b/fs/cifs/connect.c > @@ -2754,21 +2754,21 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, > > /* > * When the server supports very large writes via POSIX extensions, we can > - * allow up to 2^24 - PAGE_CACHE_SIZE. > + * allow up to 2^24-1, minus the size of a WRITE_AND_X header, not including > + * the RFC1001 length. > * > * Note that this might make for "interesting" allocation problems during > - * writeback however (as we have to allocate an array of pointers for the > - * pages). A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. > + * writeback however as we have to allocate an array of pointers for the > + * pages. A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. > */ > -#define CIFS_MAX_WSIZE ((1<<24) - PAGE_CACHE_SIZE) > +#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4) > > /* > - * When the server doesn't allow large posix writes, default to a wsize of > - * 128k - PAGE_CACHE_SIZE -- one page less than the largest frame size > - * described in RFC1001. This allows space for the header without going over > - * that by default. > + * When the server doesn't allow large posix writes, only allow a wsize of > + * 128k minus the size of the WRITE_AND_X header. That allows for a write up > + * to the maximum size described by RFC1002. > */ > -#define CIFS_MAX_RFC1001_WSIZE (128 * 1024 - PAGE_CACHE_SIZE) > +#define CIFS_MAX_RFC1002_WSIZE (128 * 1024 - sizeof(WRITE_REQ) + 4) > > /* > * The default wsize is 1M. find_get_pages seems to return a maximum of 256 > @@ -2787,11 +2787,18 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info) > > /* can server support 24-bit write sizes? (via UNIX extensions) */ > if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) > - wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1001_WSIZE); > + wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE); > > - /* no CAP_LARGE_WRITE_X? Limit it to 16 bits */ > - if (!(server->capabilities & CAP_LARGE_WRITE_X)) > - wsize = min_t(unsigned int, wsize, USHRT_MAX); > + /* > + * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set? > + * Limit it to max buffer offered by the server, minus the size of the > + * WRITEX header, not including the 4 byte RFC1001 length. > + */ > + if (!(server->capabilities & CAP_LARGE_WRITE_X) || > + (!(server->capabilities & CAP_UNIX) && > + (server->sec_mode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)))) > + wsize = min_t(unsigned int, wsize, > + server->maxBuf - sizeof(WRITE_REQ) + 4); > > /* hard limit of CIFS_MAX_WSIZE */ > wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); > -- > 1.7.5.4 > > -- Thanks, Steve -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html