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:
parent
44aedad5dd
commit
af80a98ace
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue