aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-06-24 11:35:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-06-24 11:35:04 -0400
commit143e859d05d0abf4c3b67c64c93695d59fd41342 (patch)
tree4d2539b109ccc76775dc45e07e02694399f81002 /fs
parent46e4edbf7ea9cf26665eb9f90c0fc7688d1a51ed (diff)
parent1190f6a067bf27b2ee7e06ec0776a17fe0f6c4d8 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: cifs: fix wsize negotiation to respect max buffer size and active signing (try #4) CIFS: Fix problem with 3.0-rc1 null user mount failure
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/connect.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 12cf72dd0c42..c761935eab8c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2750,21 +2750,21 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2750 2750
2751/* 2751/*
2752 * When the server supports very large writes via POSIX extensions, we can 2752 * When the server supports very large writes via POSIX extensions, we can
2753 * allow up to 2^24 - PAGE_CACHE_SIZE. 2753 * allow up to 2^24-1, minus the size of a WRITE_AND_X header, not including
2754 * the RFC1001 length.
2754 * 2755 *
2755 * Note that this might make for "interesting" allocation problems during 2756 * Note that this might make for "interesting" allocation problems during
2756 * writeback however (as we have to allocate an array of pointers for the 2757 * writeback however as we have to allocate an array of pointers for the
2757 * pages). A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096. 2758 * pages. A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096.
2758 */ 2759 */
2759#define CIFS_MAX_WSIZE ((1<<24) - PAGE_CACHE_SIZE) 2760#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4)
2760 2761
2761/* 2762/*
2762 * When the server doesn't allow large posix writes, default to a wsize of 2763 * When the server doesn't allow large posix writes, only allow a wsize of
2763 * 128k - PAGE_CACHE_SIZE -- one page less than the largest frame size 2764 * 128k minus the size of the WRITE_AND_X header. That allows for a write up
2764 * described in RFC1001. This allows space for the header without going over 2765 * to the maximum size described by RFC1002.
2765 * that by default.
2766 */ 2766 */
2767#define CIFS_MAX_RFC1001_WSIZE (128 * 1024 - PAGE_CACHE_SIZE) 2767#define CIFS_MAX_RFC1002_WSIZE (128 * 1024 - sizeof(WRITE_REQ) + 4)
2768 2768
2769/* 2769/*
2770 * The default wsize is 1M. find_get_pages seems to return a maximum of 256 2770 * The default wsize is 1M. find_get_pages seems to return a maximum of 256
@@ -2783,11 +2783,18 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
2783 2783
2784 /* can server support 24-bit write sizes? (via UNIX extensions) */ 2784 /* can server support 24-bit write sizes? (via UNIX extensions) */
2785 if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP)) 2785 if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
2786 wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1001_WSIZE); 2786 wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE);
2787 2787
2788 /* no CAP_LARGE_WRITE_X? Limit it to 16 bits */ 2788 /*
2789 if (!(server->capabilities & CAP_LARGE_WRITE_X)) 2789 * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set?
2790 wsize = min_t(unsigned int, wsize, USHRT_MAX); 2790 * Limit it to max buffer offered by the server, minus the size of the
2791 * WRITEX header, not including the 4 byte RFC1001 length.
2792 */
2793 if (!(server->capabilities & CAP_LARGE_WRITE_X) ||
2794 (!(server->capabilities & CAP_UNIX) &&
2795 (server->sec_mode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED))))
2796 wsize = min_t(unsigned int, wsize,
2797 server->maxBuf - sizeof(WRITE_REQ) + 4);
2791 2798
2792 /* hard limit of CIFS_MAX_WSIZE */ 2799 /* hard limit of CIFS_MAX_WSIZE */
2793 wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE); 2800 wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
@@ -2937,7 +2944,11 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data,
2937 2944
2938 if (volume_info->nullauth) { 2945 if (volume_info->nullauth) {
2939 cFYI(1, "null user"); 2946 cFYI(1, "null user");
2940 volume_info->username = ""; 2947 volume_info->username = kzalloc(1, GFP_KERNEL);
2948 if (volume_info->username == NULL) {
2949 rc = -ENOMEM;
2950 goto out;
2951 }
2941 } else if (volume_info->username) { 2952 } else if (volume_info->username) {
2942 /* BB fixme parse for domain name here */ 2953 /* BB fixme parse for domain name here */
2943 cFYI(1, "Username: %s", volume_info->username); 2954 cFYI(1, "Username: %s", volume_info->username);