JDK-6593729 : After failed file close, do not repeat the close operation.
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 5.0u11
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-08-16
  • Updated: 2010-12-07
  • Resolved: 2007-09-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other JDK 6 JDK 7
5.0u14 b02Fixed 6u4Fixed 7Resolved
When a close() operation on an OS file descriptor is succesful, the record of the FD is set to -1, and on subsequent close() operations the actual call to the OS' close() is not performed.

If an error occurs in the OS' close(), we do not set our record of the FD to -1, so subsequent calls will re-attempt the close().

We should not re-attempt the close().  

If the underlying OS library/syscall close() fails, e.g. Stale NFS Handle, then this is a permanent problem.  Also, the fd number may be available for reuse by other operations allocating file descriptors.  

A customer testcase has demonstrated a FileInputStream.close() throwing an exception due to "Stale NFS Handle", and subsequent calls to close() giving "Bad File Handle".

If the fd is considered closed by the OS, the number could get reused: so it could become valid.  We should mark the fd as -1 as soon as close() fails, and not retry the close again - or we risk closing a vaild fd created by some other thread.

[ removed my own comment that we could retry after ENOSPC: this can happen over NFS, but the fd does become invalid after the failed close - we should not retry the close() ]

EINTR is also possible, but we already restart in that case.

EVALUATION As description and suggested fix.

SUGGESTED FIX src/solaris/native/java/io/ $ sccs diffs -C io_util_md.c ------- io_util_md.c ------- *** /tmp/sccs.eMaWGZ Wed Aug 22 02:35:47 2007 --- io_util_md.c Wed Aug 22 02:28:08 2007 *************** *** 54,64 **** close(devnull); } } else if (fd != -1) { ! if (JVM_Close(fd) == -1) { JNU_ThrowIOExceptionWithLastError(env, "close failed"); - } else { - SET_FD(this, -1, fid); - } } } --- 54,62 ---- close(devnull); } } else if (fd != -1) { ! SET_FD(this, -1, fid); ! if (JVM_Close(fd) == -1) JNU_ThrowIOExceptionWithLastError(env, "close failed"); } } [ editing my earlier suggestion ] Similarly for Windows.