diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index f1a18e2922e..a5e04c4ce09 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -38,6 +38,9 @@ Release 2.6.4 - UNRELEASED HDFS-8767. RawLocalFileSystem.listStatus() returns null for UNIX pipefile. (Kanaka Kumar Avvaru via wheat9) + HDFS-9294. DFSClient deadlock when close file and failed to renew lease. + (Brahma Reddy Battula via szetszwo) + Release 2.6.3 - 2015-12-17 INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSOutputStream.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSOutputStream.java index 21e4d4e7523..942653c337e 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSOutputStream.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSOutputStream.java @@ -2171,13 +2171,15 @@ private synchronized void start() { * Aborts this output stream and releases any system * resources associated with this stream. */ - synchronized void abort() throws IOException { - if (closed) { - return; + void abort() throws IOException { + synchronized (this) { + if (closed) { + return; + } + streamer.setLastException(new IOException("Lease timeout of " + + (dfsClient.getHdfsTimeout() / 1000) + " seconds expired.")); + closeThreads(true); } - streamer.setLastException(new IOException("Lease timeout of " - + (dfsClient.getHdfsTimeout()/1000) + " seconds expired.")); - closeThreads(true); dfsClient.endFileLease(fileId); } @@ -2204,39 +2206,42 @@ private void closeThreads(boolean force) throws IOException { * resources associated with this stream. */ @Override - public synchronized void close() throws IOException { - if (closed) { - IOException e = lastException.getAndSet(null); - if (e == null) - return; - else - throw e; - } - - try { - flushBuffer(); // flush from all upper layers - - if (currentPacket != null) { - waitAndQueueCurrentPacket(); + public void close() throws IOException { + synchronized (this) { + if (closed) { + IOException e = lastException.getAndSet(null); + if (e == null) + return; + else + throw e; } - if (bytesCurBlock != 0) { - // send an empty packet to mark the end of the block - currentPacket = createPacket(0, 0, bytesCurBlock, currentSeqno++); - currentPacket.lastPacketInBlock = true; - currentPacket.syncBlock = shouldSyncBlock; - } + try { + flushBuffer(); // flush from all upper layers - flushInternal(); // flush all data to Datanodes - // get last block before destroying the streamer - ExtendedBlock lastBlock = streamer.getBlock(); - closeThreads(false); - completeFile(lastBlock); - dfsClient.endFileLease(fileId); - } catch (ClosedChannelException e) { - } finally { - closed = true; + if (currentPacket != null) { + waitAndQueueCurrentPacket(); + } + + if (bytesCurBlock != 0) { + // send an empty packet to mark the end of the block + currentPacket = createPacket(0, 0, bytesCurBlock, currentSeqno++); + currentPacket.lastPacketInBlock = true; + currentPacket.syncBlock = shouldSyncBlock; + } + + flushInternal(); // flush all data to Datanodes + // get last block before destroying the streamer + ExtendedBlock lastBlock = streamer.getBlock(); + closeThreads(false); + completeFile(lastBlock); + + } catch (ClosedChannelException e) { + } finally { + closed = true; + } } + dfsClient.endFileLease(fileId); } // should be called holding (this) lock since setTestFilename() may