[jcifs] Patch: Support for LARGE_READX and LARGE_WRITEX
Allen, Michael B (RSCH)
Michael_B_Allen at ml.com
Wed Feb 5 17:06:26 EST 2003
I couldn't get this to work. Please send a diff -Naur old new style patch. I may have
manually botched something because it was getting caught in an enless loop
spewing data. I didn't have time to really investigate why.
I did apply the >4GB patch.
Thanks,
Mike
> -----Original Message-----
> From: Thomas Krammer [SMTP:TKrammer at nxn-software.com]
> Sent: Tuesday, January 28, 2003 12:41 PM
> To: 'jcifs at lists.samba.org'
> Subject: [jcifs] Patch: Support for LARGE_READX and LARGE_WRITEX
>
> Hi,
>
> I updated jCIFS 0.7.1 to support the LARGE_READX and LARGE_WRITEX
> capabilities. This results in an increased download speed (in my tests the
> speed was more than doubled) when dealing with a Windows 2000 server.
> When I connected to a Samba server the code didn't show a similar speedup
> because the negotiated buffer size already is 64k (4k on Windows).
>
> Client: Windows 2000 Pro Java 1.4.1_01
> Server: Windows 2000 Pro
>
> Transferred data: 51.5 MB file
>
> Download:
> jCIFS 0.7.1: 3316kB/s
> modified version: 6993kB/s
> cmd /c copy: 7941kB/s
>
> Upload:
> jCIFS 0.7.1: 2137kB/s
> modified version: 2646kB/s
> cmd /c copy: 5450kB/s
>
> The reported values are the average of 5 runs of the same test.
>
> Some notes:
>
> 1) I used ethereal to look at the SMB packages created by Windows 2000. It
> seems the native Window 2000 SMB client uses 0xF000 as maximum buffer size.
> So I restricted the buffer size to that value.
> 2) Currently I don't know why the upload doesn't similar benefit from the
> increased buffer size as the download.
> 3) To benefit from the increased read/write buffer size the caller should
> use buffers > 4kB in calls to SmbFileInputStream.read() and
> SmbFileOutputStream.write(). To collect the performance data above I used
> 32kB buffers.
> 4) The supplied patch is against my modified version and not against the
> orginal jCIFS 0.7.1 code. So you may have to apply the patch I recently sent
> to this mailing list (support for files >4GB) first.
>
> The code:
>
> *** jcifs_0.7.1\src\jcifs\smb\SmbFileOutputStream.java Mon Jan 27 18:51:38
> 2003
> --- jcifs_0.7.1_mod\src\jcifs\smb\SmbFileOutputStream.java Tue Jan 28
> 15:16:00 2003
> ***************
> *** 33,38 ****
> --- 33,39 ----
> private SmbFile file;
> private boolean append;
> private int openFlags, writeSize;
> + private int writeSizeFile;
> private long fp;
> private byte[] tmp = new byte[1];
>
> ***************
> *** 107,114 ****
> --- 108,124 ----
> }
> }
> file.open( openFlags );
> +
> writeSize = Math.min( file.tree.session.transport.snd_buf_size -
> 70,
>
> file.tree.session.transport.server.maxBufferSize - 70 );
> +
> +
> if(file.tree.session.transport.hasCapability(ServerMessageBlock.CAP_LARGE_WR
> ITEX)) {
> + // Server supports LARGE_WRITEX.
> + // The request's size may exceed the negotiated buffer size.
> + writeSizeFile =
> Math.min(file.tree.session.transport.snd_buf_size - 70, 0xF000);
> + } else {
> + writeSizeFile = writeSize;
> + }
> }
>
> /**
> ***************
> *** 165,175 ****
> }
> }
>
> Log.println( Log.WARNINGS, "smb write warning",
> " fid=" + file.fid + ",off=" + off + ",len=" + len
> );
> int w;
> do {
> ! w = len > writeSize ? writeSize : len;
> file.send( new SmbComWriteAndX( file.fid, fp, len - w, b, off,
> w, null ),
> new
> SmbComWriteAndXResponse() );
> fp += w;
> --- 175,188 ----
> }
> }
>
> + // Only enable large blocks for disk files.
> + int blockSize = (file.getType() == SmbFile.TYPE_FILESYSTEM) ?
> writeSizeFile : writeSize;
> +
> Log.println( Log.WARNINGS, "smb write warning",
> " fid=" + file.fid + ",off=" + off + ",len=" + len
> );
> int w;
> do {
> ! w = len > blockSize ? blockSize : len;
> file.send( new SmbComWriteAndX( file.fid, fp, len - w, b, off,
> w, null ),
> new
> SmbComWriteAndXResponse() );
> fp += w;
>
> *** jcifs_0.7.1\src\jcifs\smb\SmbFileInputStream.java Wed Jan 15 21:56:44
> 2003
> --- jcifs_0.7.1_mod\src\jcifs\smb\SmbFileInputStream.java Tue Jan 28
> 15:15:51 2003
> ***************
> *** 33,38 ****
> --- 33,39 ----
> private SmbFile file;
> private long fp;
> private int off, readSize, openFlags;
> + private int readSizeFile;
> private byte[] tmp = new byte[1];
>
> /**
> ***************
> *** 67,74 ****
> --- 68,84 ----
> this.file = file;
> this.openFlags = openFlags;
> file.open( openFlags );
> +
> readSize = Math.min( file.tree.session.transport.rcv_buf_size -
> 70,
>
> file.tree.session.transport.server.maxBufferSize - 70 );
> +
> +
> if(file.tree.session.transport.hasCapability(ServerMessageBlock.CAP_LARGE_RE
> ADX)) {
> + // Server supports LARGE_READX.
> + // The request's size may exceed the negotiated buffer size.
> + readSizeFile =
> Math.min(file.tree.session.transport.rcv_buf_size - 70, 0xF000);
> + } else {
> + readSizeFile = readSize;
> + }
> }
>
> /**
> ***************
> *** 133,141 ****
> response.responseTimeout = 0;
> }
>
> int r, n;
> do {
> ! r = len > readSize ? readSize : len;
> //System.out.println( "len=" + len + ",r=" + r + ",fp=" + fp );
> try {
> file.send( new SmbComReadAndX( file.fid, fp, r, null ),
> response );
> --- 143,154 ----
> response.responseTimeout = 0;
> }
>
> + // Only enable large blocks for disk files.
> + int blockSize = (file.getType() == SmbFile.TYPE_FILESYSTEM) ?
> readSizeFile : readSize;
> +
> int r, n;
> do {
> ! r = len > blockSize ? blockSize : len;
> //System.out.println( "len=" + len + ",r=" + r + ",fp=" + fp );
> try {
> file.send( new SmbComReadAndX( file.fid, fp, r, null ),
> response );
>
> *** jcifs_0.7.1\src\jcifs\smb\SmbTransport.java Wed Jan 15 21:56:44 2003
> --- jcifs_0.7.1_mod\src\jcifs\smb\SmbTransport.java Tue Jan 28 15:18:36
> 2003
> ***************
> *** 42,48 ****
> private static final int DEFAULT_SO_TIMEOUT = 15000;
> private static final int PUSHBACK_BUF_SIZE = 64;
> private static final int DEFAULT_RCV_BUF_SIZE = 60416;
> ! private static final int DEFAULT_SND_BUF_SIZE = 5000;
>
> static final int MID_OFFSET = 30;
> static final int HEADER_LENGTH = 32;
> --- 42,48 ----
> private static final int DEFAULT_SO_TIMEOUT = 15000;
> private static final int PUSHBACK_BUF_SIZE = 64;
> private static final int DEFAULT_RCV_BUF_SIZE = 60416;
> ! private static final int DEFAULT_SND_BUF_SIZE = 60416;
>
> static final int MID_OFFSET = 30;
> static final int HEADER_LENGTH = 32;
> ***************
> *** 93,99 ****
> ServerMessageBlock.FLAGS2_LONG_FILENAMES |
>
> ServerMessageBlock.FLAGS2_UNICODE );
> int capabilities = Config.getInt( "jcifs.smb.client.capabilities",
> ! ServerMessageBlock.CAP_UNICODE |
> ServerMessageBlock.CAP_NT_SMBS );
> String nativeOs = Config.getProperty( "jcifs.smb.client.nativeOs",
> System.getProperty( "os.name" ));
> String nativeLanMan = Config.getProperty(
> "jcifs.smb.client.nativeLanMan", "jCIFS" );
> --- 93,100 ----
> ServerMessageBlock.FLAGS2_LONG_FILENAMES |
>
> ServerMessageBlock.FLAGS2_UNICODE );
> int capabilities = Config.getInt( "jcifs.smb.client.capabilities",
> ! ServerMessageBlock.CAP_UNICODE |
> ServerMessageBlock.CAP_NT_SMBS |
> ! ServerMessageBlock.CAP_LARGE_READX |
> ServerMessageBlock.CAP_LARGE_WRITEX);
> String nativeOs = Config.getProperty( "jcifs.smb.client.nativeOs",
> System.getProperty( "os.name" ));
> String nativeLanMan = Config.getProperty(
> "jcifs.smb.client.nativeLanMan", "jCIFS" );
>
> *** jcifs_0.7.1\src\jcifs\smb\ServerMessageBlock.java Wed Jan 15 21:56:44
> 2003
> --- jcifs_0.7.1_mod\src\jcifs\smb\ServerMessageBlock.java Mon Jan 27
> 20:08:35 2003
> ***************
> *** 60,65 ****
> --- 60,67 ----
> 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_LARGE_READX = 0x4000;
> + static final int CAP_LARGE_WRITEX = 0x8000;
>
> // file attribute encoding
> static final int ATTR_READONLY = 0x01;
More information about the jcifs
mailing list