Skip to content

Commit 1120dc8

Browse files
committed
HDFS-5982. Need to update snapshot manager when applying editlog for deleting a snapshottable directory. Contributed by Jing Zhao.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1570395 13f79535-47bb-0310-9956-ffa450edef68
1 parent c9fcc6e commit 1120dc8

File tree

3 files changed

+54
-16
lines changed

3 files changed

+54
-16
lines changed

hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,9 @@ Release 2.4.0 - UNRELEASED
543543
HDFS-5944. LeaseManager:findLeaseWithPrefixPath can't handle path like /a/b/
544544
and cause SecondaryNameNode failed do checkpoint (Yunjiong Zhao via brandonli)
545545

546+
HDFS-5982. Need to update snapshot manager when applying editlog for deleting
547+
a snapshottable directory. (jing9)
548+
546549
BREAKDOWN OF HDFS-5698 SUBTASKS AND RELATED JIRAS
547550

548551
HDFS-5717. Save FSImage header in protobuf. (Haohui Mai via jing9)

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,20 +1317,12 @@ boolean delete(String src, BlocksMapUpdateInfo collectedBlocks,
13171317
if (!deleteAllowed(inodesInPath, src) ) {
13181318
filesRemoved = -1;
13191319
} else {
1320-
// Before removing the node, first check if the targetNode is for a
1321-
// snapshottable dir with snapshots, or its descendants have
1322-
// snapshottable dir with snapshots
1323-
final INode targetNode = inodesInPath.getLastINode();
13241320
List<INodeDirectorySnapshottable> snapshottableDirs =
13251321
new ArrayList<INodeDirectorySnapshottable>();
1326-
checkSnapshot(targetNode, snapshottableDirs);
1322+
checkSnapshot(inodesInPath.getLastINode(), snapshottableDirs);
13271323
filesRemoved = unprotectedDelete(inodesInPath, collectedBlocks,
13281324
removedINodes, now);
1329-
if (snapshottableDirs.size() > 0) {
1330-
// There are some snapshottable directories without snapshots to be
1331-
// deleted. Need to update the SnapshotManager.
1332-
namesystem.removeSnapshottableDirs(snapshottableDirs);
1333-
}
1325+
namesystem.removeSnapshottableDirs(snapshottableDirs);
13341326
}
13351327
} finally {
13361328
writeUnlock();
@@ -1392,18 +1384,25 @@ boolean isNonEmptyDirectory(String path) throws UnresolvedLinkException {
13921384
* @param src a string representation of a path to an inode
13931385
* @param mtime the time the inode is removed
13941386
* @throws SnapshotAccessControlException if path is in RO snapshot
1395-
*/
1387+
*/
13961388
void unprotectedDelete(String src, long mtime) throws UnresolvedLinkException,
1397-
QuotaExceededException, SnapshotAccessControlException {
1389+
QuotaExceededException, SnapshotAccessControlException, IOException {
13981390
assert hasWriteLock();
13991391
BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo();
14001392
List<INode> removedINodes = new ChunkedArrayList<INode>();
14011393

14021394
final INodesInPath inodesInPath = rootDir.getINodesInPath4Write(
14031395
normalizePath(src), false);
1404-
final long filesRemoved = deleteAllowed(inodesInPath, src) ?
1405-
unprotectedDelete(inodesInPath, collectedBlocks,
1406-
removedINodes, mtime) : -1;
1396+
long filesRemoved = -1;
1397+
if (deleteAllowed(inodesInPath, src)) {
1398+
List<INodeDirectorySnapshottable> snapshottableDirs =
1399+
new ArrayList<INodeDirectorySnapshottable>();
1400+
checkSnapshot(inodesInPath.getLastINode(), snapshottableDirs);
1401+
filesRemoved = unprotectedDelete(inodesInPath, collectedBlocks,
1402+
removedINodes, mtime);
1403+
namesystem.removeSnapshottableDirs(snapshottableDirs);
1404+
}
1405+
14071406
if (filesRemoved >= 0) {
14081407
getFSNamesystem().removePathAndBlocks(src, collectedBlocks,
14091408
removedINodes);

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/snapshot/TestSnapshotDeletion.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.apache.hadoop.hdfs.MiniDFSCluster;
4141
import org.apache.hadoop.hdfs.MiniDFSNNTopology;
4242
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
43+
import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction;
4344
import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo;
4445
import org.apache.hadoop.hdfs.server.blockmanagement.BlockManager;
4546
import org.apache.hadoop.hdfs.server.namenode.FSDirectory;
@@ -128,7 +129,42 @@ public void testDeleteDirectoryWithSnapshot() throws Exception {
128129
exception.expectMessage(error);
129130
hdfs.delete(sub, true);
130131
}
131-
132+
133+
/**
134+
* Test applying editlog of operation which deletes a snapshottable directory
135+
* without snapshots. The snapshottable dir list in snapshot manager should be
136+
* updated.
137+
*/
138+
@Test (timeout=300000)
139+
public void testApplyEditLogForDeletion() throws Exception {
140+
final Path foo = new Path("/foo");
141+
final Path bar1 = new Path(foo, "bar1");
142+
final Path bar2 = new Path(foo, "bar2");
143+
hdfs.mkdirs(bar1);
144+
hdfs.mkdirs(bar2);
145+
146+
// allow snapshots on bar1 and bar2
147+
hdfs.allowSnapshot(bar1);
148+
hdfs.allowSnapshot(bar2);
149+
assertEquals(2, cluster.getNamesystem().getSnapshotManager()
150+
.getNumSnapshottableDirs());
151+
assertEquals(2, cluster.getNamesystem().getSnapshotManager()
152+
.getSnapshottableDirs().length);
153+
154+
// delete /foo
155+
hdfs.delete(foo, true);
156+
cluster.restartNameNode(0);
157+
// the snapshottable dir list in snapshot manager should be empty
158+
assertEquals(0, cluster.getNamesystem().getSnapshotManager()
159+
.getNumSnapshottableDirs());
160+
assertEquals(0, cluster.getNamesystem().getSnapshotManager()
161+
.getSnapshottableDirs().length);
162+
hdfs.setSafeMode(SafeModeAction.SAFEMODE_ENTER);
163+
hdfs.saveNamespace();
164+
hdfs.setSafeMode(SafeModeAction.SAFEMODE_LEAVE);
165+
cluster.restartNameNode(0);
166+
}
167+
132168
/**
133169
* Deleting directory with snapshottable descendant with snapshots must fail.
134170
*/

0 commit comments

Comments
 (0)