[jcifs] Issues with closing destination file in SmbFile.copyTo0()

Vella, Shon svella at idauto.net
Thu Jun 19 07:56:36 MDT 2014


I have a customer that's been having issues with files being left open
when copying directory hierarchies (i.e. moving home directories). I
don't know for sure that this is the issue the customer is seeing, but
looking over the code for copyTo0() it is apparent that there are two
issues related to closing the destination file.

1. There are no guarantees that the last block has been written by
writer thread before Trans2SetFileInformation is sent or dest.close()
is called.
2. If there are any exceptions thrown during the read/write loop or
when sending Trans2SetFileInformation, dest.close() will not be called
at all, leaving it open until the session is dropped.

I've created a patch that addresses both problems. Note that the patch
builds depends on a previous patch
(http://article.gmane.org/gmane.network.samba.java/9348) that I've
submitted.

--- src/main/java/jcifs/smb/SmbFile.java (revision 5164)
+++ src/main/java/jcifs/smb/SmbFile.java (revision )
@@ -36,8 +36,6 @@
 import jcifs.dcerpc.*;
 import jcifs.dcerpc.msrpc.*;

-import java.util.Date;
-
 /**
  * This class represents a resource on an SMB network. Mainly these
  * resources are files and directories however an <code>SmbFile</code>
@@ -2105,13 +2103,7 @@
             if( e != null ) {
                 throw e;
             }
-            while( !ready ) {
-                try {
-                    wait();
-                } catch( InterruptedException ie ) {
-                    throw new SmbException( dest.url.toString(), ie );
-                }
-            }
+            waitUntilReady();
             if( e != null ) {
                 throw e;
             }
@@ -2123,6 +2115,16 @@
             notify();
         }

+        synchronized void waitUntilReady() throws SmbException {
+            while( !ready ) {
+                try {
+                    wait();
+                } catch( InterruptedException ie ) {
+                    throw new SmbException( dest.url.toString(), ie );
+                }
+            }
+        }
+
         public void run() {
             synchronized( this ) {
                 try {
@@ -2231,27 +2233,33 @@
                     }
                 }

+                try {
-                i = 0;
-                off = 0L;
+                    i = 0;
+                    off = 0L;
-                for( ;; ) {
+                    for (; ; ) {
-                    req.setParam( fid, off, bsize );
+                        req.setParam(fid, off, bsize);
-                    resp.setParam( b[i], 0 );
+                        resp.setParam(b[i], 0);
-                    send( req, resp );
+                        send(req, resp);

-                    if( resp.dataLength <= 0 ) {
+                        if (resp.dataLength <= 0) {
-                        break;
-                    }
+                            break;
+                        }

-                    w.write( b[i], resp.dataLength, dest, off );
+                        w.write(b[i], resp.dataLength, dest, off);

-                    i = i == 1 ? 0 : 1;
-                    off += resp.dataLength;
-                }
+                        i = i == 1 ? 0 : 1;
+                        off += resp.dataLength;
+                    }
-
+                } finally {
+                    try {
+                        w.waitUntilReady();
-                dest.send( new Trans2SetFileInformation(
+                        dest.send(new Trans2SetFileInformation(
-                        dest.fid, attributes, createTime, lastModified ),
+                                        dest.fid, attributes,
createTime, lastModified),
-                        new Trans2SetFileInformationResponse() );
+                                new Trans2SetFileInformationResponse());
+                    } finally {
-                dest.close( 0L );
+                        dest.close(0L);
+                    }
+                }
             } catch( SmbException se ) {

                 if (ignoreCopyToException == false)


Shon Vella
Product Engineer
iDENTiTYAUTOMATiON
www.identityautomation.com


More information about the jCIFS mailing list