diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-24 11:35:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-24 11:35:04 -0400 |
commit | 143e859d05d0abf4c3b67c64c93695d59fd41342 (patch) | |
tree | 4d2539b109ccc76775dc45e07e02694399f81002 /fs | |
parent | 46e4edbf7ea9cf26665eb9f90c0fc7688d1a51ed (diff) | |
parent | 1190f6a067bf27b2ee7e06ec0776a17fe0f6c4d8 (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.c | 39 |
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); |