Re: [PATCH] cifs: fix wsize negotiation to respect max buffer size and active signing (try #4)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux