diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 984637a625..0a82d20ccf 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -873,6 +873,9 @@ Release 2.5.0 - UNRELEASED HDFS-6312. WebHdfs HA failover is broken on secure clusters. (daryn via tucu) + HDFS-6618. FSNamesystem#delete drops the FSN lock between removing INodes + from the tree and deleting them from the inode map (kihwal via cmccabe) + Release 2.4.1 - 2014-06-23 INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java index 0901f54b24..4604a9a3df 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java @@ -654,7 +654,7 @@ boolean unprotectedRenameTo(String src, String dst, long timestamp, dstIIP.getLatestSnapshotId(), collectedBlocks, removedINodes, true).get(Quota.NAMESPACE); getFSNamesystem().removePathAndBlocks(src, collectedBlocks, - removedINodes); + removedINodes, false); } } @@ -1190,7 +1190,7 @@ void unprotectedDelete(String src, long mtime) throws UnresolvedLinkException, if (filesRemoved >= 0) { getFSNamesystem().removePathAndBlocks(src, collectedBlocks, - removedINodes); + removedINodes, false); } } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java index 944d45b175..1d015b09bb 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java @@ -3525,7 +3525,7 @@ private boolean deleteInternal(String src, boolean recursive, getEditLog().logDelete(src, mtime, logRetryCache); incrDeletedFileCount(filesRemoved); // Blocks/INodes will be handled later - removePathAndBlocks(src, null, null); + removePathAndBlocks(src, null, removedINodes, true); ret = true; } finally { writeUnlock(); @@ -3534,13 +3534,6 @@ private boolean deleteInternal(String src, boolean recursive, removeBlocks(collectedBlocks); // Incremental deletion of blocks collectedBlocks.clear(); - dir.writeLock(); - try { - dir.removeFromInodeMap(removedINodes); - } finally { - dir.writeUnlock(); - } - removedINodes.clear(); if (NameNode.stateChangeLog.isDebugEnabled()) { NameNode.stateChangeLog.debug("DIR* Namesystem.delete: " + src +" is removed"); @@ -3578,14 +3571,24 @@ void removeBlocks(BlocksMapUpdateInfo blocks) { * @param blocks Containing the list of blocks to be deleted from blocksMap * @param removedINodes Containing the list of inodes to be removed from * inodesMap + * @param acquireINodeMapLock Whether to acquire the lock for inode removal */ void removePathAndBlocks(String src, BlocksMapUpdateInfo blocks, - List removedINodes) { + List removedINodes, final boolean acquireINodeMapLock) { assert hasWriteLock(); leaseManager.removeLeaseWithPrefixPath(src); // remove inodes from inodesMap if (removedINodes != null) { - dir.removeFromInodeMap(removedINodes); + if (acquireINodeMapLock) { + dir.writeLock(); + } + try { + dir.removeFromInodeMap(removedINodes); + } finally { + if (acquireINodeMapLock) { + dir.writeUnlock(); + } + } removedINodes.clear(); } if (blocks == null) {