summaryrefslogtreecommitdiff
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-18 20:28:11 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-18 20:28:11 +0400
commita9866ba47c3e7b7665b5f08fa6ef684f3285c939 (patch)
tree1d3977c467148892532f683ac5fcc4534c672b5d /fs/cifs/connect.c
parent331ae4962b975246944ea039697a8f1cadce42bb (diff)
parentcd60042cc1392e79410dc8de9e9c1abb38a29e57 (diff)
downloadlinux-a9866ba47c3e7b7665b5f08fa6ef684f3285c939.tar.xz
Merge git://git.samba.org/sfrench/cifs-2.6
Pull CIFS fixes from Steve French. * git://git.samba.org/sfrench/cifs-2.6: cifs: always update the inode cache with the results from a FIND_* cifs: when CONFIG_HIGHMEM is set, serialize the read/write kmaps cifs: on CONFIG_HIGHMEM machines, limit the rsize/wsize to the kmap space Initialise mid_q_entry before putting it on the pending queue
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 0ae86ddf2213..94b7788c3189 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3445,6 +3445,18 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
+/*
+ * On hosts with high memory, we can't currently support wsize/rsize that are
+ * larger than we can kmap at once. Cap the rsize/wsize at
+ * LAST_PKMAP * PAGE_SIZE. We'll never be able to fill a read or write request
+ * larger than that anyway.
+ */
+#ifdef CONFIG_HIGHMEM
+#define CIFS_KMAP_SIZE_LIMIT (LAST_PKMAP * PAGE_CACHE_SIZE)
+#else /* CONFIG_HIGHMEM */
+#define CIFS_KMAP_SIZE_LIMIT (1<<24)
+#endif /* CONFIG_HIGHMEM */
+
static unsigned int
cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
{
@@ -3475,6 +3487,9 @@ cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
wsize = min_t(unsigned int, wsize,
server->maxBuf - sizeof(WRITE_REQ) + 4);
+ /* limit to the amount that we can kmap at once */
+ wsize = min_t(unsigned int, wsize, CIFS_KMAP_SIZE_LIMIT);
+
/* hard limit of CIFS_MAX_WSIZE */
wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
@@ -3516,6 +3531,9 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
if (!(server->capabilities & CAP_LARGE_READ_X))
rsize = min_t(unsigned int, CIFSMaxBufSize, rsize);
+ /* limit to the amount that we can kmap at once */
+ rsize = min_t(unsigned int, rsize, CIFS_KMAP_SIZE_LIMIT);
+
/* hard limit of CIFS_MAX_RSIZE */
rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE);