[CIFS] Add in some missing flags and cifs README and TODO corrections
Signed-off-by: Steve French <sfrench@us.ibm.com>
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index a9b6bc5..b4d388d 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -8,7 +8,10 @@
default uid and gid for files when they are certain that the uids or
gids on the server do not match those of the client. Make "sec=none"
mount override username (so that null user connection is attempted)
-to match what documentation said.
+to match what documentation said. Support for very large reads, over 127K,
+available to some newer servers (such as Samba 3.0.26 and later but
+note that it also requires setting CIFSMaxBufSize at module install
+time to a larger value which may hurt performance in some cases).
Version 1.48
------------
diff --git a/fs/cifs/README b/fs/cifs/README
index 4d01697..eb3efd5 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -301,10 +301,21 @@
during the local client kernel build will be used.
If server does not support Unicode, this parameter is
unused.
- rsize default read size (usually 16K)
- wsize default write size (usually 16K, 32K is often better over GigE)
- maximum wsize currently allowed by CIFS is 57344 (14 4096 byte
- pages)
+ rsize default read size (usually 16K). The client currently
+ can not use rsize larger than CIFSMaxBufSize. CIFSMaxBufSize
+ defaults to 16K and may be changed (from 8K to the maximum
+ kmalloc size allowed by your kernel) at module install time
+ for cifs.ko. Setting CIFSMaxBufSize to a very large value
+ will cause cifs to use more memory and may reduce performance
+ in some cases. To use rsize greater than 127K (the original
+ cifs protocol maximum) also requires that the server support
+ a new Unix Capability flag (for very large read) which some
+ newer servers (e.g. Samba 3.0.26 or later) do. rsize can be
+ set from a minimum of 2048 to a maximum of 130048 (127K or
+ CIFSMaxBufSize, whichever is smaller)
+ wsize default write size (default 57344)
+ maximum wsize currently allowed by CIFS is 57344 (fourteen
+ 4096 byte pages)
rw mount the network share read-write (note that the
server may still consider the share read-only)
ro mount network share read-only
@@ -582,10 +593,10 @@
echo 1 > /proc/fs/cifs/traceSMB
-Two other experimental features are under development and to test
-require enabling CONFIG_CIFS_EXPERIMENTAL
+Two other experimental features are under development. To test these
+requires enabling CONFIG_CIFS_EXPERIMENTAL
- More efficient write operations
+ ipv6 enablement
DNOTIFY fcntl: needed for support of directory change
notification and perhaps later for file leases)
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index 78b620e..d57dc29 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -106,6 +106,12 @@
succeed but still return access denied (appears to be Windows
server not cifs client problem) and has not been reproduced recently.
NTFS partitions do not have this problem.
+4) Unix/POSIX capabilities are reset after reconnection, and affect
+a few fields in the tree connection but we do do not know which
+superblocks to apply these changes to. We should probably walk
+the list of superblocks to set these. Also need to check the
+flags on the second mount to the same share, and see if we
+can do the same trick that NFS does to remount duplicate shares.
Misc testing to do
==================
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index d619ca7..802d27d 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -712,6 +712,7 @@
#define REQ_OPLOCK 0x00000002
#define REQ_BATCHOPLOCK 0x00000004
#define REQ_OPENDIRONLY 0x00000008
+#define REQ_EXTENDED_INFO 0x00000010
typedef struct smb_com_open_req { /* also handles create */
struct smb_hdr hdr; /* wct = 24 */
@@ -1885,15 +1886,19 @@
#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */
#define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based
calls including posix open
- and posix unlink */
+ and posix unlink */
+#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up
+ to 0xFFFF00 */
+#define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080
+
#ifdef CONFIG_CIFS_POSIX
/* Can not set pathnames cap yet until we send new posix create SMB since
otherwise server can treat such handles opened with older ntcreatex
(by a new client which knows how to send posix path ops)
as non-posix handles (can affect write behavior with byte range locks.
We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */
-/* #define CIFS_UNIX_CAP_MASK 0x0000003b */
-#define CIFS_UNIX_CAP_MASK 0x0000001b
+/* #define CIFS_UNIX_CAP_MASK 0x000000fb */
+#define CIFS_UNIX_CAP_MASK 0x000000db
#else
#define CIFS_UNIX_CAP_MASK 0x00000013
#endif /* CONFIG_CIFS_POSIX */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f4e9266..4a2af78 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/connect.c
*
- * Copyright (C) International Business Machines Corp., 2002,2006
+ * Copyright (C) International Business Machines Corp., 2002,2007
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -1650,19 +1650,19 @@
}
cap &= CIFS_UNIX_CAP_MASK;
- if(vol_info && vol_info->no_psx_acl)
+ if (vol_info && vol_info->no_psx_acl)
cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
- else if(CIFS_UNIX_POSIX_ACL_CAP & cap) {
+ else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
cFYI(1,("negotiated posix acl support"));
if(sb)
sb->s_flags |= MS_POSIXACL;
}
- if(vol_info && vol_info->posix_paths == 0)
+ if (vol_info && vol_info->posix_paths == 0)
cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
- else if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+ else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
cFYI(1,("negotiate posix pathnames"));
- if(sb)
+ if (sb)
CIFS_SB(sb)->mnt_cifs_flags |=
CIFS_MOUNT_POSIX_PATHS;
}
@@ -1670,21 +1670,35 @@
/* We might be setting the path sep back to a different
form if we are reconnecting and the server switched its
posix path capability for this share */
- if(sb && (CIFS_SB(sb)->prepathlen > 0))
+ if (sb && (CIFS_SB(sb)->prepathlen > 0))
CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
+
+ if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
+ if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
+ CIFS_SB(sb)->rsize = 127 * 1024;
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1,("larger reads not supported by srv"));
+#endif
+ }
+ }
+
cFYI(1,("Negotiate caps 0x%x",(int)cap));
#ifdef CONFIG_CIFS_DEBUG2
- if(cap & CIFS_UNIX_FCNTL_CAP)
+ if (cap & CIFS_UNIX_FCNTL_CAP)
cFYI(1,("FCNTL cap"));
- if(cap & CIFS_UNIX_EXTATTR_CAP)
+ if (cap & CIFS_UNIX_EXTATTR_CAP)
cFYI(1,("EXTATTR cap"));
- if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
+ if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
cFYI(1,("POSIX path cap"));
- if(cap & CIFS_UNIX_XATTR_CAP)
+ if (cap & CIFS_UNIX_XATTR_CAP)
cFYI(1,("XATTR cap"));
- if(cap & CIFS_UNIX_POSIX_ACL_CAP)
+ if (cap & CIFS_UNIX_POSIX_ACL_CAP)
cFYI(1,("POSIX ACL cap"));
+ if (cap & CIFS_UNIX_LARGE_READ_CAP)
+ cFYI(1,("very large read cap"));
+ if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
+ cFYI(1,("very large write cap"));
#endif /* CIFS_DEBUG2 */
if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
cFYI(1,("setting capabilities failed"));
@@ -1935,13 +1949,14 @@
cERROR(1,("rsize %d too large, using MaxBufSize",
volume_info.rsize));
cifs_sb->rsize = CIFSMaxBufSize;
- } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
+ } else if ((volume_info.rsize) &&
+ (volume_info.rsize <= CIFSMaxBufSize))
cifs_sb->rsize = volume_info.rsize;
else /* default */
cifs_sb->rsize = CIFSMaxBufSize;
if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
- cERROR(1,("wsize %d too large using 4096 instead",
+ cERROR(1,("wsize %d too large, using 4096 instead",
volume_info.wsize));
cifs_sb->wsize = 4096;
} else if (volume_info.wsize)
@@ -1960,7 +1975,7 @@
if (cifs_sb->rsize < 2048) {
cifs_sb->rsize = 2048;
/* Windows ME may prefer this */
- cFYI(1,("readsize set to minimum 2048"));
+ cFYI(1,("readsize set to minimum: 2048"));
}
/* calculate prepath */
cifs_sb->prepath = volume_info.prepath;
@@ -2116,7 +2131,13 @@
/* tell server which Unix caps we support */
if (tcon->ses->capabilities & CAP_UNIX)
reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
-
+ else if(cifs_sb->rsize > (1024 * 127)) {
+ cifs_sb->rsize = 1024 * 127;
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1,("no very large read support, rsize 127K"));
+#endif
+
+ }
if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
cifs_sb->wsize = min(cifs_sb->wsize,
(tcon->ses->server->maxBuf -
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 94d5b49..5f1b707 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1720,7 +1720,9 @@
pTcon = cifs_sb->tcon;
pagevec_init(&lru_pvec, 0);
-
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1,("rpages: num pages %d", num_pages));
+#endif
for (i = 0; i < num_pages; ) {
unsigned contig_pages;
struct page *tmp_page;
@@ -1753,7 +1755,10 @@
/* Read size needs to be in multiples of one page */
read_size = min_t(const unsigned int, read_size,
cifs_sb->rsize & PAGE_CACHE_MASK);
-
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1,("rpages: read size 0x%x contiguous pages %d",
+ read_size, contig_pages));
+#endif
rc = -EAGAIN;
while (rc == -EAGAIN) {
if ((open_file->invalidHandle) &&