From 2e7261d75a3197d77ffe05f26e366a2413c5e2fb Mon Sep 17 00:00:00 2001 From: Colin McCabe Date: Thu, 10 Jul 2014 03:54:20 +0000 Subject: [PATCH] HDFS-6618. FSNamesystem#delete drops the FSN lock between removing INodes from the tree and deleting them from the inode map (kihwal via cmccabe) git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1609381 13f79535-47bb-0310-9956-ffa450edef68 --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 +++ .../hdfs/server/namenode/FSDirectory.java | 4 ++-- .../hdfs/server/namenode/FSNamesystem.java | 23 +++++++++++-------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index b69431a735f..2505ded3d90 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -615,6 +615,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 321af0fd69d..1aaab941fd2 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 @@ -656,7 +656,7 @@ public class FSDirectory implements Closeable { dstIIP.getLatestSnapshotId(), collectedBlocks, removedINodes, true).get(Quota.NAMESPACE); getFSNamesystem().removePathAndBlocks(src, collectedBlocks, - removedINodes); + removedINodes, false); } } @@ -1194,7 +1194,7 @@ public class FSDirectory implements Closeable { 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 b2a8651290f..20bf536e08e 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 @@ public class FSNamesystem implements Namesystem, FSClusterStats, 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 @@ public class FSNamesystem implements Namesystem, FSClusterStats, 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 @@ public class FSNamesystem implements Namesystem, FSClusterStats, * @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) {