HDFS-6551. Rename with OVERWRITE option may throw NPE when the target file/directory is a reference INode. Contributed by Jing Zhao.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1603612 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
52d18aa217
commit
4cf94aaf80
|
@ -656,6 +656,9 @@ Release 2.5.0 - UNRELEASED
|
||||||
HDFS-6552. add DN storage to a BlockInfo will not replace the different
|
HDFS-6552. add DN storage to a BlockInfo will not replace the different
|
||||||
storage from same DN. (Amir Langer via Arpit Agarwal)
|
storage from same DN. (Amir Langer via Arpit Agarwal)
|
||||||
|
|
||||||
|
HDFS-6551. Rename with OVERWRITE option may throw NPE when the target
|
||||||
|
file/directory is a reference INode. (jing9)
|
||||||
|
|
||||||
BREAKDOWN OF HDFS-2006 SUBTASKS AND RELATED JIRAS
|
BREAKDOWN OF HDFS-2006 SUBTASKS AND RELATED JIRAS
|
||||||
|
|
||||||
HDFS-6299. Protobuf for XAttr and client-side implementation. (Yi Liu via umamahesh)
|
HDFS-6299. Protobuf for XAttr and client-side implementation. (Yi Liu via umamahesh)
|
||||||
|
|
|
@ -44,7 +44,6 @@ import org.apache.hadoop.fs.XAttr;
|
||||||
import org.apache.hadoop.fs.XAttrSetFlag;
|
import org.apache.hadoop.fs.XAttrSetFlag;
|
||||||
import org.apache.hadoop.fs.permission.AclEntry;
|
import org.apache.hadoop.fs.permission.AclEntry;
|
||||||
import org.apache.hadoop.fs.permission.AclStatus;
|
import org.apache.hadoop.fs.permission.AclStatus;
|
||||||
import org.apache.hadoop.fs.permission.FsAction;
|
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
import org.apache.hadoop.fs.permission.PermissionStatus;
|
import org.apache.hadoop.fs.permission.PermissionStatus;
|
||||||
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
||||||
|
@ -891,9 +890,10 @@ public class FSDirectory implements Closeable {
|
||||||
|
|
||||||
boolean undoRemoveDst = false;
|
boolean undoRemoveDst = false;
|
||||||
INode removedDst = null;
|
INode removedDst = null;
|
||||||
|
long removedNum = 0;
|
||||||
try {
|
try {
|
||||||
if (dstInode != null) { // dst exists remove it
|
if (dstInode != null) { // dst exists remove it
|
||||||
if (removeLastINode(dstIIP) != -1) {
|
if ((removedNum = removeLastINode(dstIIP)) != -1) {
|
||||||
removedDst = dstIIP.getLastINode();
|
removedDst = dstIIP.getLastINode();
|
||||||
undoRemoveDst = true;
|
undoRemoveDst = true;
|
||||||
}
|
}
|
||||||
|
@ -933,13 +933,15 @@ public class FSDirectory implements Closeable {
|
||||||
long filesDeleted = -1;
|
long filesDeleted = -1;
|
||||||
if (removedDst != null) {
|
if (removedDst != null) {
|
||||||
undoRemoveDst = false;
|
undoRemoveDst = false;
|
||||||
BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo();
|
if (removedNum > 0) {
|
||||||
List<INode> removedINodes = new ChunkedArrayList<INode>();
|
BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo();
|
||||||
filesDeleted = removedDst.cleanSubtree(Snapshot.CURRENT_STATE_ID,
|
List<INode> removedINodes = new ChunkedArrayList<INode>();
|
||||||
dstIIP.getLatestSnapshotId(), collectedBlocks, removedINodes, true)
|
filesDeleted = removedDst.cleanSubtree(Snapshot.CURRENT_STATE_ID,
|
||||||
.get(Quota.NAMESPACE);
|
dstIIP.getLatestSnapshotId(), collectedBlocks, removedINodes,
|
||||||
getFSNamesystem().removePathAndBlocks(src, collectedBlocks,
|
true).get(Quota.NAMESPACE);
|
||||||
removedINodes);
|
getFSNamesystem().removePathAndBlocks(src, collectedBlocks,
|
||||||
|
removedINodes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snapshottableDirs.size() > 0) {
|
if (snapshottableDirs.size() > 0) {
|
||||||
|
|
|
@ -171,8 +171,6 @@ public class TestRenameWithSnapshots {
|
||||||
private static boolean existsInDiffReport(List<DiffReportEntry> entries,
|
private static boolean existsInDiffReport(List<DiffReportEntry> entries,
|
||||||
DiffType type, String relativePath) {
|
DiffType type, String relativePath) {
|
||||||
for (DiffReportEntry entry : entries) {
|
for (DiffReportEntry entry : entries) {
|
||||||
System.out.println("DiffEntry is:" + entry.getType() + "\""
|
|
||||||
+ new String(entry.getRelativePath()) + "\"");
|
|
||||||
if ((entry.getType() == type)
|
if ((entry.getType() == type)
|
||||||
&& ((new String(entry.getRelativePath())).compareTo(relativePath) == 0)) {
|
&& ((new String(entry.getRelativePath())).compareTo(relativePath) == 0)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -2374,4 +2372,46 @@ public class TestRenameWithSnapshots {
|
||||||
// save namespace and restart
|
// save namespace and restart
|
||||||
restartClusterAndCheckImage(true);
|
restartClusterAndCheckImage(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRenameWithOverWrite() throws Exception {
|
||||||
|
final Path root = new Path("/");
|
||||||
|
final Path foo = new Path(root, "foo");
|
||||||
|
final Path file1InFoo = new Path(foo, "file1");
|
||||||
|
final Path file2InFoo = new Path(foo, "file2");
|
||||||
|
final Path file3InFoo = new Path(foo, "file3");
|
||||||
|
DFSTestUtil.createFile(hdfs, file1InFoo, 1L, REPL, SEED);
|
||||||
|
DFSTestUtil.createFile(hdfs, file2InFoo, 1L, REPL, SEED);
|
||||||
|
DFSTestUtil.createFile(hdfs, file3InFoo, 1L, REPL, SEED);
|
||||||
|
final Path bar = new Path(root, "bar");
|
||||||
|
hdfs.mkdirs(bar);
|
||||||
|
|
||||||
|
SnapshotTestHelper.createSnapshot(hdfs, root, "s0");
|
||||||
|
// move file1 from foo to bar
|
||||||
|
final Path fileInBar = new Path(bar, "file1");
|
||||||
|
hdfs.rename(file1InFoo, fileInBar);
|
||||||
|
// rename bar to newDir
|
||||||
|
final Path newDir = new Path(root, "newDir");
|
||||||
|
hdfs.rename(bar, newDir);
|
||||||
|
// move file2 from foo to newDir
|
||||||
|
final Path file2InNewDir = new Path(newDir, "file2");
|
||||||
|
hdfs.rename(file2InFoo, file2InNewDir);
|
||||||
|
// move file3 from foo to newDir and rename it to file1, this will overwrite
|
||||||
|
// the original file1
|
||||||
|
final Path file1InNewDir = new Path(newDir, "file1");
|
||||||
|
hdfs.rename(file3InFoo, file1InNewDir, Rename.OVERWRITE);
|
||||||
|
SnapshotTestHelper.createSnapshot(hdfs, root, "s1");
|
||||||
|
|
||||||
|
SnapshotDiffReport report = hdfs.getSnapshotDiffReport(root, "s0", "s1");
|
||||||
|
LOG.info("DiffList is \n\"" + report.toString() + "\"");
|
||||||
|
List<DiffReportEntry> entries = report.getDiffList();
|
||||||
|
assertEquals(7, entries.size());
|
||||||
|
assertTrue(existsInDiffReport(entries, DiffType.MODIFY, ""));
|
||||||
|
assertTrue(existsInDiffReport(entries, DiffType.MODIFY, foo.getName()));
|
||||||
|
assertTrue(existsInDiffReport(entries, DiffType.DELETE, bar.getName()));
|
||||||
|
assertTrue(existsInDiffReport(entries, DiffType.CREATE, newDir.getName()));
|
||||||
|
assertTrue(existsInDiffReport(entries, DiffType.DELETE, "foo/file1"));
|
||||||
|
assertTrue(existsInDiffReport(entries, DiffType.DELETE, "foo/file2"));
|
||||||
|
assertTrue(existsInDiffReport(entries, DiffType.DELETE, "foo/file3"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue