Re: Large Read/Write Patch
"M. D." <[email protected]> Wed, 17 Dec 2014 15:30:34 +0200 (EET)
| Newsgroups | gmane.network.samba.java |
|---|---|
| Message-ID | <[email protected]> |
Hi, I'm uploading a new patch. It now contains checks if signatures are desired. If that's the case then the old buffer size is used. Best regards, M.D >-------- Оригинално писмо -------- >От: M. D. >Относно: Re: [jcifs] Large Read/Write Patch >До: Robin Jansohn >Изпратено на: Сряда, 2014, Декември 17 10:58:08 EET > > > Hello, > >I also confirm that read/write operations with the patch applied are significantly faster. > >However, I think there is a problem with the patch: > >According to the official SMB documentation: >http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/[MS-SMB].pdf > >... sections 2.2.4.5, 2.2.4.5.2: >"Capabilities (4 bytes): A 32-bit field providing a set of server capability indicators. This bit field is >used to indicate to the client which features are supported by the server. Any value not listed in the >following table is unused. The server MUST set the unused bits to zero. The client MUST ignore >these bits.". > >The CAP_LARGE_WRITEX flag that is part of the Capabilities (4 bytes) field is responsible for: > >"The server supports large write operations. This >capability affects the maximum size, in bytes, of the >server buffer for receiving an SMB_COM_WRITE_ANDX >client request. When this capability is set by the server >(and set by the client in the >SMB_COM_SESSION_SETUP_ANDX request), then the >maximum server buffer size of bytes it writes can >exceed the MaxBufferSize field. Therefore, a client >can send a single SMB_COM_WRITE_ANDX request up >to this size. >When signing is active on a connection, then clients >MUST limit write lengths to the MaxBufferSize value >negotiated by the server, irrespective of the value of >the CAP_LARGE_WRITEX flag." > >... so it is true that we can safely ignore the MaxBufferSize and send larger chunks of data UNLESS signing is active on a connection. Therefore, I think checks for signing should be added to the patch. > >Hope that helps! > > >Best regards, >M.D > > > > > >-------- Оригинално писмо -------- > >От: Robin Jansohn > >Относно: Re: [jcifs] Large Read/Write Patch > >До: [email protected] > >Изпратено на: Понеделник, 2014, Декември 15 09:08:49 EET > > > > > >No, I'm using a Maven repository and although I explicitly excluded the > >package it somehow did not work as expected. The test itself is run in a > >simple Main class, no webapp or similar large application. > > > > > > > >-- > >View this message in context: http://samba.2283325.n4.nabble.com/Large-Read-Write-Patch-tp3674893p4677877.html > >Sent from the Samba - jcifs mailing list archive at Nabble.com. > > >
LargeReadWrite.patch
(application/octet-stream, 6.6 KB)
### Eclipse Workspace Patch 1.0
#P jcifs
Index: src/jcifs/smb/SmbFileOutputStream.java
===================================================================
--- src/jcifs/smb/SmbFileOutputStream.java (revision 54857)
+++ src/jcifs/smb/SmbFileOutputStream.java (working copy)
@@ -33,7 +33,7 @@
private SmbFile file;
private boolean append, useNTSmbs;
- private int openFlags, access, writeSize;
+ private int openFlags, writeSizeFile, access, writeSize;
private long fp;
private byte[] tmp = new byte[1];
private SmbComWriteAndX reqx;
@@ -142,6 +142,11 @@
file.open( openFlags, access | SmbConstants.FILE_WRITE_DATA, SmbFile.ATTR_NORMAL, 0 );
this.openFlags &= ~(SmbFile.O_CREAT | SmbFile.O_TRUNC); /* in case close and reopen */
writeSize = file.tree.session.transport.snd_buf_size - 70;
+ boolean isSignatureActive =
+ file.tree.session.transport.server.signaturesRequired ||
+ (file.tree.session.transport.server.signaturesEnabled && SmbTransport.SIGNPREF);
+ if((file.tree.session.transport.server.capabilities & SmbConstants.CAP_LARGE_WRITEX) == SmbConstants.CAP_LARGE_WRITEX && !isSignatureActive) {
+ writeSizeFile = Math.min(SmbConstants.RCV_BUF_SIZE - 70, 0xFFFF - 70);
+ } else {
+ writeSizeFile = writeSize;
+ }
useNTSmbs = file.tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS );
if( useNTSmbs ) {
@@ -233,15 +238,17 @@
int w;
do {
- w = len > writeSize ? writeSize : len;
+ int blockSize = (file.getType() == SmbFile.TYPE_FILESYSTEM) ? writeSizeFile : writeSize;
+ w = len > blockSize ? blockSize : len;
+
if( useNTSmbs ) {
reqx.setParam( file.fid, fp, len - w, b, off, w );
-if ((flags & 1) != 0) {
- reqx.setParam( file.fid, fp, len, b, off, w );
- reqx.writeMode = 0x8;
-} else {
- reqx.writeMode = 0;
-}
+ if ((flags & 1) != 0) {
+ reqx.setParam( file.fid, fp, len, b, off, w );
+ reqx.writeMode = 0x8;
+ } else {
+ reqx.writeMode = 0;
+ }
file.send( reqx, rspx );
fp += rspx.count;
len -= rspx.count;
Index: src/jcifs/smb/SmbRandomAccessFile.java
===================================================================
--- src/jcifs/smb/SmbRandomAccessFile.java (revision 54857)
+++ src/jcifs/smb/SmbRandomAccessFile.java (working copy)
@@ -55,8 +55,19 @@
throw new IllegalArgumentException( "Invalid mode" );
}
file.open( openFlags, access, SmbFile.ATTR_NORMAL, options );
- readSize = file.tree.session.transport.rcv_buf_size - 70;
- writeSize = file.tree.session.transport.snd_buf_size - 70;
+ boolean isSignatureActive =
+ file.tree.session.transport.server.signaturesRequired ||
+ (file.tree.session.transport.server.signaturesEnabled && SmbTransport.SIGNPREF);
+ if((file.tree.session.transport.server.capabilities & SmbConstants.CAP_LARGE_READX) == SmbConstants.CAP_LARGE_READX && !isSignatureActive) {
+ readSize = Math.min(SmbConstants.RCV_BUF_SIZE - 70, 0xFFFF -70);
+ } else {
+ readSize = file.tree.session.transport.rcv_buf_size - 70;
+ }
+
+ if((file.tree.session.transport.server.capabilities & SmbConstants.CAP_LARGE_WRITEX) == SmbConstants.CAP_LARGE_WRITEX && !isSignatureActive) {
+ writeSize = Math.min(SmbConstants.SND_BUF_SIZE - 70, 0xFFFF - 70);
+ } else {
+ writeSize = Math.min( file.tree.session.transport.snd_buf_size - 70,
+ file.tree.session.transport.server.maxBufferSize - 70 );
+ }
fp = 0L;
}
Index: src/jcifs/smb/SmbConstants.java
===================================================================
--- src/jcifs/smb/SmbConstants.java (revision 54857)
+++ src/jcifs/smb/SmbConstants.java (working copy)
@@ -12,8 +12,8 @@
static final int DEFAULT_MAX_MPX_COUNT = 10;
static final int DEFAULT_RESPONSE_TIMEOUT = 30000;
static final int DEFAULT_SO_TIMEOUT = 35000;
- static final int DEFAULT_RCV_BUF_SIZE = 60416;
- static final int DEFAULT_SND_BUF_SIZE = 16644;
+ static final int DEFAULT_RCV_BUF_SIZE = 0xFFFF;
+ static final int DEFAULT_SND_BUF_SIZE = 0xFFFF;
static final int DEFAULT_SSN_LIMIT = 250;
static final InetAddress LADDR = Config.getLocalHost();
@@ -61,7 +61,9 @@
static final int CAP_LEVEL_II_OPLOCKS = 0x0080;
static final int CAP_LOCK_AND_READ = 0x0100;
static final int CAP_NT_FIND = 0x0200;
- static final int CAP_DFS = 0x1000;
+ static final int CAP_DFS = 0x1000;
+ static final int CAP_LARGE_READX = 0x4000;
+ static final int CAP_LARGE_WRITEX = 0x8000;
static final int CAP_EXTENDED_SECURITY = 0x80000000;
// file attribute encoding
Index: src/jcifs/smb/SmbFileInputStream.java
===================================================================
--- src/jcifs/smb/SmbFileInputStream.java (revision 54857)
+++ src/jcifs/smb/SmbFileInputStream.java (working copy)
@@ -34,7 +34,7 @@
public class SmbFileInputStream extends InputStream {
private long fp;
- private int readSize, openFlags, access;
+ private int readSize, readSizeFile, openFlags, access;
private byte[] tmp = new byte[1];
SmbFile file;
@@ -76,7 +76,12 @@
file.connect0();
}
readSize = Math.min( file.tree.session.transport.rcv_buf_size - 70,
- file.tree.session.transport.server.maxBufferSize - 70 );
+ file.tree.session.transport.server.maxBufferSize - 70 );
+ boolean isSignatureActive =
+ file.tree.session.transport.server.signaturesRequired ||
+ (file.tree.session.transport.server.signaturesEnabled && SmbTransport.SIGNPREF);
+ if((file.tree.session.transport.server.capabilities & SmbConstants.CAP_LARGE_READX) == SmbConstants.CAP_LARGE_READX && !isSignatureActive) {
+ readSizeFile = Math.min(SmbConstants.RCV_BUF_SIZE - 70, 0xFFFF - 70);
+ } else {
+ readSizeFile = readSize;
+ }
}
protected IOException seToIoe(SmbException se) {
@@ -168,7 +173,8 @@
int r, n;
do {
- r = len > readSize ? readSize : len;
+ int blockSize = (file.getType() == SmbFile.TYPE_FILESYSTEM) ? readSizeFile : readSize;
+ r = len > blockSize ? blockSize : len;
if( file.log.level >= 4 )
file.log.println( "read: len=" + len + ",r=" + r + ",fp=" + fp );