HDFS-7926. NameNode implementation of ClientProtocol.truncate(..) is not idempotent. Contributed by Tsz Wo Nicholas Sze

(cherry picked from commit f446669afb)
This commit is contained in:
Brandon Li 2015-03-13 10:42:22 -07:00
parent 44aedad5dd
commit af80a98ace
4 changed files with 21 additions and 0 deletions

View File

@ -839,6 +839,9 @@ Release 2.7.0 - UNRELEASED
HDFS-6833. DirectoryScanner should not register a deleting block with HDFS-6833. DirectoryScanner should not register a deleting block with
memory of DataNode. (Shinichi Yamashita via szetszwo) memory of DataNode. (Shinichi Yamashita via szetszwo)
HDFS-7926. NameNode implementation of ClientProtocol.truncate(..) is not
idempotent (Tsz Wo Nicholas Sze via brandonli)
BREAKDOWN OF HDFS-7584 SUBTASKS AND RELATED JIRAS BREAKDOWN OF HDFS-7584 SUBTASKS AND RELATED JIRAS
HDFS-7720. Quota by Storage Type API, tools and ClientNameNode HDFS-7720. Quota by Storage Type API, tools and ClientNameNode

View File

@ -383,6 +383,7 @@ public class BlockInfoContiguousUnderConstruction extends BlockInfoContiguous {
private void appendUCParts(StringBuilder sb) { private void appendUCParts(StringBuilder sb) {
sb.append("{UCState=").append(blockUCState) sb.append("{UCState=").append(blockUCState)
.append(", truncateBlock=" + truncateBlock)
.append(", primaryNodeIndex=").append(primaryNodeIndex) .append(", primaryNodeIndex=").append(primaryNodeIndex)
.append(", replicas=["); .append(", replicas=[");
if (replicas != null) { if (replicas != null) {

View File

@ -2021,6 +2021,21 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
"Cannot truncate lazy persist file " + src); "Cannot truncate lazy persist file " + src);
} }
// Check if the file is already being truncated with the same length
final BlockInfoContiguous last = file.getLastBlock();
if (last != null && last.getBlockUCState() == BlockUCState.UNDER_RECOVERY) {
final Block truncateBlock
= ((BlockInfoContiguousUnderConstruction)last).getTruncateBlock();
if (truncateBlock != null) {
final long truncateLength = file.computeFileSize(false, false)
+ truncateBlock.getNumBytes();
if (newLength == truncateLength) {
return false;
}
}
}
// Opening an existing file for truncate. May need lease recovery. // Opening an existing file for truncate. May need lease recovery.
recoverLeaseInternal(RecoverLeaseOp.TRUNCATE_FILE, recoverLeaseInternal(RecoverLeaseOp.TRUNCATE_FILE,
iip, src, clientName, clientMachine, false); iip, src, clientName, clientMachine, false);

View File

@ -166,6 +166,8 @@ public class TestFileTruncate {
LOG.info("newLength=" + newLength + ", isReady=" + isReady); LOG.info("newLength=" + newLength + ", isReady=" + isReady);
assertEquals("File must be closed for truncating at the block boundary", assertEquals("File must be closed for truncating at the block boundary",
isReady, newLength % BLOCK_SIZE == 0); isReady, newLength % BLOCK_SIZE == 0);
assertEquals("Truncate is not idempotent",
isReady, fs.truncate(p, newLength));
if (!isReady) { if (!isReady) {
checkBlockRecovery(p); checkBlockRecovery(p);
} }