[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