[jcifs] Trouble deleting directory-- receive error message "The process cannot access the file because it is being used by another process."

Brian Bernstein brian.bernstein at indorse-tech.com
Tue Apr 8 20:53:13 GMT 2008


Well, I did some more testing and found some interesting quirks that
seem to be specific to the CIFS protocol and is apparently quite
common when deleting with this new method.

First, after a file is changed to set delete on close, it can not be
opened or even queried again.  However, despite this, the server will
still show the file in its listings until it is actually deleted.

Attempts to access this file, which is pending deletion, results in a
NT_STATUS_DELETE_PENDING error.

This also generates another issue, as while the the file is still
pending, it can not be overwritten until it is actually deleted, as it
can not be opened again.

With these caveats, it is probably best not to include it into the
main stream code, but might still be worth while as a separate patch
for those who are having similar issues as we and would like to try
deleting as a pending delete.

I can probably post the patch by the end of the week, there's just a
few minor issues I want to see if I can fix up with it first.

-Brian

On 02/04/2008, Michael B Allen <miallen at ioplex.com> wrote:
> On Wed, 2 Apr 2008 09:43:34 -0400
>
> "Brian Bernstein" <brian.bernstein at indorse-tech.com> wrote:
>
>
> > I think I've finally gotten to the bottom of this issue.
>  >
>  > It appears the issue is not in the share permissions or the
>  > FILE_SHARE_DELETE flag, but rather in the manner that JCIFS goes about
>  > deleting files.
>  >
>  > JCIFS attempts to delete a file via a SmbComDelete.  However, it was
>  > noticed that other clients go about deleting files differently. . . by
>  > opening them up, calling a SetFileInformation with the
>  > SetDeleteOnClose flag, then closing them afterwards.  It apears that
>  > windows will honor the FILE_SHARE_DELETE flag only when deleting in
>  > this way and will still return a "in use by another process" error if
>  > deleting in the way that JCIFS does with the SmbComDelete command.
>
>
> Interesting. I never noticed that (probably because it was all
>  written in the NT 4.0 days).
>
>
>  > I have patched my copy of JCIFS to try SmbComDelete, and then go about
>  > doing it the latter way if it gets the "in user by another process"
>  > error.  So far, it appears to be working as expected.  I will continue
>  > some more testing and then send in a patch which I hope will be
>  > included into the next release.
>  >
>  > -Brian
>  >
>  > On 03/12/2007, Brian Bernstein <brian.bernstein at indorse-tech.com> wrote:
>  > > It looks like the FILE_SHARE_DELETE flag is broken.
>  > >
>  > > I just tried a much simpler case (I had not tested this case before as I
>  > > have had the FILE_SHARE_READ and FILE_SHARE_WRITE flags work properly
>  > > before).
>  > >
>  > > In this case, I don't bother creating a resource in a new directory, I just
>  > > create a new file with all the share permissions, and then try to delete it
>  > > afterwards.  When this happens, I get the same error:
>  > >
>  > > jcifs.smb.SmbException: The process cannot access the file because it is
>  > > being used by another process.
>  > >      at
>  > > jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:514)
>  > >      at jcifs.smb.SmbTransport.send(SmbTransport.java :614)
>  > >      at jcifs.smb.SmbSession.send(SmbSession.java:239)
>  > >      at jcifs.smb.SmbTree.send(SmbTree.java:109)
>  > >      at jcifs.smb.SmbFile.send(SmbFile.java:695)
>  > >      at jcifs.smb.SmbFile.delete(SmbFile.java:2380)
>  > >      at jcifs.smb.SmbFile.delete(SmbFile.java:2324)
>  > >
>  > > Also note that I am trying to implement a web interface for manipulating
>  > > SMB/CIFS repositories.  This is being deployed on a JBoss server.
>  > >
>  > > I do not store SmbFile handles between requests.  As the delete is in a
>  > > successive request, I simply create a new SmbFile of that url, so I am
>  > > assuming that I am creating a new connection to that resource and am not
>  > > using the same connection as was used to create the resource initially.
>  > >
>  > > Sorry for confusing the issue initially, I just never thought to have tried
>  > > this test initially.
>  > >
>  > > I hope this helps in troubleshooting this.
>  > >
>  > > -Brian
>  > >
>  > >
>  > > On 03/12/2007, Michael B Allen <miallen at ioplex.com> wrote:
>  > > > On Mon, 3 Dec 2007 12:01:30 -0500
>  > > > "Brian Bernstein"
>  > > <brian.bernstein at indorse-tech.com> wrote:
>  > > >
>  > > > > I am having trouble deleting a directory with contents within it
>  > > > > shortly after creating said directory.
>  > > > >
>  > > > > Here's what I do to receive this error:
>  > > > > First, I create a directory on a resource, with full share permissions.
>  > > > > SmbFile file = new SmbFile(dirUrl, credentials,
>  > > > >
>  > > SmbFile.FILE_SHARE_READ|SmbFile.FILE_SHARE_WRITE|SmbFile.FILE_SHARE_DELETE);
>  > > > > file.mkDir();
>  > > > >
>  > > > > Then I place files within this directory.
>  > > > > SmbFile file = new SmbFile(dirUrl/fileName, credentials,
>  > > > >
>  > > SmbFile.FILE_SHARE_READ|SmbFile.FILE_SHARE_WRITE|SmbFile.FILE_SHARE_DELETE);
>  > > > > file.getOutputStream.write(fileContents);
>  > > > >
>  > > > > (this step can be repeated a few times).
>  > > > >
>  > > > > Lastly, I try to delete the directory, however the original SmbFile
>  > > > > reference has since been lost, so a new connection is made.
>  > > >
>  > > > Hi Brian,
>  > > >
>  > > > That should not happen. Connections are reused (unless you're using a
>  > > > special class loader - like in a web server).
>  > >
>  > > > > SmbFile file = new SmbFile(dirUrl, credentials,
>  > > > >
>  > > SmbFile.FILE_SHARE_READ|SmbFile.FILE_SHARE_WRITE|SmbFile.FILE_SHARE_DELETE
>  > > );
>  > > > > file.delete();
>  > > > >
>  > > > > However, the deletion fails and instead I get this exception:
>  > > > > jcifs.smb.SmbException: The process cannot access the file because it
>  > > > > is being used by another process.
>  > > > >       at
>  > > jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:514)
>  > > > >       at
>  > > jcifs.smb.SmbTransport.send(SmbTransport.java:614)
>  > > >
>  > > > If all of the files are opened with
>  > > >
>  > > SmbFile.FILE_SHARE_READ|SmbFile.FILE_SHARE_WRITE|SmbFile.FILE_SHARE_DELETE
>  > > > the above error should not happen. Sounds like a bug (somewhere).
>  > > >
>  > > > > First off, I was under the impression that if I open these resources
>  > > > > with full share permissions
>  > > > > (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE)
>  > > that I would not
>  > > > > be having these issues (isn't that what the FILE_SHARE_DELETE
>  > > > > permissions is for?).
>  > > >
>  > > > True.
>  > > >
>  > > > > Do these permissions not apply towards
>  > > > > directories or do not work when recursing?
>  > > >
>  > > > An mkdir doesn't create a file handle so the shareAccess parameter should
>  > > > not be applicable.
>  > > >
>  > > > > I believe this issue is a timeout issue.  If the original socket(s)
>  > > > > are allowed to timeout before the attempt is made, the delete works
>  > > > > without an issue, however this timeout appears to be on the magnitude
>  > > > > of minutes, which is too long.
>  > > >
>  > > > This is somewhat moot in light of previous errors.
>  > > >
>  > > > >
>  > > > > I had attempted to override this with the setConnectTimeout() but
>  > > > > found it quite difficult to find an appropriate value to set this to
>  > > > > as setting it too low would cause problems when trying to write to the
>  > > > > connection.
>  > > > >
>  > > > > Is there a way to perform an explicit disconnect when done with the
>  > > connection?
>  > > >
>  > > > No. There should be no reason to explicitly disconnect a connection. One
>  > > > time someone came up with a valid (albeit exotic) reason but this case
>  > > > is not.
>  > > >
>  > > > Do you use SmbFileOutputStream? That class also accepts shareAccess flags.
>  > > >
>  > > > Otherwise, the only way to fix this would be to get a capture of a minimal
>  > > > sequence and determine what handle is responsible. First thing to do
>  > > > is to look at the shareAccess flags in WireShark and make sure they're
>  > > > right. I've messed around with those flags a few times over the years.
>  > > >
>  > > > Mike
>  > > >
>  > > > --
>  > > > Michael B Allen
>  > > > PHP Active Directory SPNEGO SSO
>  > > > http://www.ioplex.com/
>  > > >
>  > >
>  >
>  >
>  > --
>  > ======================================
>  > 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
>  > 45 5F E1 04 22 CA 29 C4 93 3F 95 05 2B 79 2A B2
>  >
>
>
>
> --
>
> Michael B Allen
>  PHP Active Directory SPNEGO SSO
>  http://www.ioplex.com/
>


-- 
======================================
09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0
45 5F E1 04 22 CA 29 C4 93 3F 95 05 2B 79 2A B2


More information about the jcifs mailing list