HDFS-13642. Creating a file with block size smaller than EC policy's cell size should fail.
(cherry picked from commit cf4108313d
)
Conflicts:
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSStripedOutputStream.java
This commit is contained in:
parent
42c6119e47
commit
a5690b29a7
|
@ -19,6 +19,7 @@ package org.apache.hadoop.hdfs.server.namenode;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.hadoop.HadoopIllegalArgumentException;
|
import org.apache.hadoop.HadoopIllegalArgumentException;
|
||||||
import org.apache.hadoop.fs.FileStatus;
|
import org.apache.hadoop.fs.FileStatus;
|
||||||
import org.apache.hadoop.fs.XAttr;
|
import org.apache.hadoop.fs.XAttr;
|
||||||
|
@ -354,16 +355,28 @@ final class FSDirErasureCodingOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the file or directory has an erasure coding policy.
|
* Get the erasure coding policy information for specified path and policy
|
||||||
|
* name. If ec policy name is given, it will be parsed and the corresponding
|
||||||
|
* policy will be returned. Otherwise, get the policy from the parents of the
|
||||||
|
* iip.
|
||||||
*
|
*
|
||||||
* @param fsn namespace
|
* @param fsn namespace
|
||||||
|
* @param ecPolicyName the ec policy name
|
||||||
* @param iip inodes in the path containing the file
|
* @param iip inodes in the path containing the file
|
||||||
* @return Whether the file or directory has an erasure coding policy.
|
* @return {@link ErasureCodingPolicy}, or null if no policy is found
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
static boolean hasErasureCodingPolicy(final FSNamesystem fsn,
|
static ErasureCodingPolicy getErasureCodingPolicy(FSNamesystem fsn,
|
||||||
final INodesInPath iip) throws IOException {
|
String ecPolicyName, INodesInPath iip) throws IOException {
|
||||||
return unprotectedGetErasureCodingPolicy(fsn, iip) != null;
|
ErasureCodingPolicy ecPolicy;
|
||||||
|
if (!StringUtils.isEmpty(ecPolicyName)) {
|
||||||
|
ecPolicy = FSDirErasureCodingOp.getErasureCodingPolicyByName(
|
||||||
|
fsn, ecPolicyName);
|
||||||
|
} else {
|
||||||
|
ecPolicy = FSDirErasureCodingOp.unprotectedGetErasureCodingPolicy(
|
||||||
|
fsn, iip);
|
||||||
|
}
|
||||||
|
return ecPolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
package org.apache.hadoop.hdfs.server.namenode;
|
package org.apache.hadoop.hdfs.server.namenode;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.apache.hadoop.HadoopIllegalArgumentException;
|
import org.apache.hadoop.HadoopIllegalArgumentException;
|
||||||
import org.apache.hadoop.fs.XAttrSetFlag;
|
import org.apache.hadoop.fs.XAttrSetFlag;
|
||||||
import org.apache.hadoop.hdfs.AddBlockFlag;
|
import org.apache.hadoop.hdfs.AddBlockFlag;
|
||||||
|
@ -551,13 +550,8 @@ class FSDirWriteFileOp {
|
||||||
boolean isStriped = false;
|
boolean isStriped = false;
|
||||||
ErasureCodingPolicy ecPolicy = null;
|
ErasureCodingPolicy ecPolicy = null;
|
||||||
if (!shouldReplicate) {
|
if (!shouldReplicate) {
|
||||||
if (!StringUtils.isEmpty(ecPolicyName)) {
|
ecPolicy = FSDirErasureCodingOp.getErasureCodingPolicy(
|
||||||
ecPolicy = FSDirErasureCodingOp.getErasureCodingPolicyByName(
|
fsd.getFSNamesystem(), ecPolicyName, existing);
|
||||||
fsd.getFSNamesystem(), ecPolicyName);
|
|
||||||
} else {
|
|
||||||
ecPolicy = FSDirErasureCodingOp.unprotectedGetErasureCodingPolicy(
|
|
||||||
fsd.getFSNamesystem(), existing);
|
|
||||||
}
|
|
||||||
if (ecPolicy != null && (!ecPolicy.isReplicationPolicy())) {
|
if (ecPolicy != null && (!ecPolicy.isReplicationPolicy())) {
|
||||||
isStriped = true;
|
isStriped = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2431,11 +2431,6 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
iip = FSDirWriteFileOp.resolvePathForStartFile(
|
iip = FSDirWriteFileOp.resolvePathForStartFile(
|
||||||
dir, pc, src, flag, createParent);
|
dir, pc, src, flag, createParent);
|
||||||
|
|
||||||
if (shouldReplicate ||
|
|
||||||
(org.apache.commons.lang.StringUtils.isEmpty(ecPolicyName) &&
|
|
||||||
!FSDirErasureCodingOp.hasErasureCodingPolicy(this, iip))) {
|
|
||||||
blockManager.verifyReplication(src, replication, clientMachine);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blockSize < minBlockSize) {
|
if (blockSize < minBlockSize) {
|
||||||
throw new IOException("Specified block size is less than configured" +
|
throw new IOException("Specified block size is less than configured" +
|
||||||
|
@ -2443,6 +2438,22 @@ public class FSNamesystem implements Namesystem, FSNamesystemMBean,
|
||||||
+ "): " + blockSize + " < " + minBlockSize);
|
+ "): " + blockSize + " < " + minBlockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shouldReplicate) {
|
||||||
|
blockManager.verifyReplication(src, replication, clientMachine);
|
||||||
|
} else {
|
||||||
|
final ErasureCodingPolicy ecPolicy = FSDirErasureCodingOp
|
||||||
|
.getErasureCodingPolicy(this, ecPolicyName, iip);
|
||||||
|
if (ecPolicy != null && (!ecPolicy.isReplicationPolicy())) {
|
||||||
|
if (blockSize < ecPolicy.getCellSize()) {
|
||||||
|
throw new IOException("Specified block size (" + blockSize
|
||||||
|
+ ") is less than the cell size (" + ecPolicy.getCellSize()
|
||||||
|
+") of the erasure coding policy (" + ecPolicy + ").");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
blockManager.verifyReplication(src, replication, clientMachine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FileEncryptionInfo feInfo = null;
|
FileEncryptionInfo feInfo = null;
|
||||||
if (!iip.isRaw() && provider != null) {
|
if (!iip.isRaw() && provider != null) {
|
||||||
EncryptionKeyInfo ezInfo = FSDirEncryptionZoneOp.getEncryptionKeyInfo(
|
EncryptionKeyInfo ezInfo = FSDirEncryptionZoneOp.getEncryptionKeyInfo(
|
||||||
|
|
|
@ -1558,8 +1558,9 @@ public class DFSTestUtil {
|
||||||
out.write("replicated".getBytes());
|
out.write("replicated".getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
try (FSDataOutputStream out = filesystem.createFile(
|
try (FSDataOutputStream out = filesystem
|
||||||
new Path(ecDir, "RS-3-2")).ecPolicyName(ecPolicyRS32.getName()).build()) {
|
.createFile(new Path(ecDir, "RS-3-2"))
|
||||||
|
.ecPolicyName(ecPolicyRS32.getName()).blockSize(1024 * 1024).build()) {
|
||||||
out.write("RS-3-2".getBytes());
|
out.write("RS-3-2".getBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.hadoop.hdfs;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -231,4 +232,19 @@ public class TestDFSStripedOutputStream {
|
||||||
StripedFileTestUtil.checkData(fs, testPath, writeBytes,
|
StripedFileTestUtil.checkData(fs, testPath, writeBytes,
|
||||||
new ArrayList<DatanodeInfo>(), null, blockSize * dataBlocks);
|
new ArrayList<DatanodeInfo>(), null, blockSize * dataBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFileBlockSizeSmallerThanCellSize() throws Exception {
|
||||||
|
final Path path = new Path("testFileBlockSizeSmallerThanCellSize");
|
||||||
|
final byte[] bytes = StripedFileTestUtil.generateBytes(cellSize * 2);
|
||||||
|
try {
|
||||||
|
DFSTestUtil.writeFile(fs, path, bytes, cellSize / 2);
|
||||||
|
fail("Creating a file with block size smaller than "
|
||||||
|
+ "ec policy's cell size should fail");
|
||||||
|
} catch (IOException expected) {
|
||||||
|
LOG.info("Caught expected exception", expected);
|
||||||
|
GenericTestUtils
|
||||||
|
.assertExceptionContains("less than the cell size", expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class TestErasureCodingExerciseAPIs {
|
||||||
private DistributedFileSystem fs;
|
private DistributedFileSystem fs;
|
||||||
private HdfsAdmin dfsAdmin;
|
private HdfsAdmin dfsAdmin;
|
||||||
private FileSystemTestWrapper fsWrapper;
|
private FileSystemTestWrapper fsWrapper;
|
||||||
private static final int BLOCK_SIZE = 1 << 14; // 16k
|
private static final int BLOCK_SIZE = 1 << 20; // 1MB
|
||||||
private ErasureCodingPolicy ecPolicy;
|
private ErasureCodingPolicy ecPolicy;
|
||||||
|
|
||||||
private static ErasureCodingPolicy getEcPolicy() {
|
private static ErasureCodingPolicy getEcPolicy() {
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class TestErasureCodingPolicies {
|
||||||
private Configuration conf;
|
private Configuration conf;
|
||||||
private MiniDFSCluster cluster;
|
private MiniDFSCluster cluster;
|
||||||
private DistributedFileSystem fs;
|
private DistributedFileSystem fs;
|
||||||
private static final int BLOCK_SIZE = 16 * 1024;
|
private static final int BLOCK_SIZE = 1024 * 1024;
|
||||||
private ErasureCodingPolicy ecPolicy;
|
private ErasureCodingPolicy ecPolicy;
|
||||||
private FSNamesystem namesystem;
|
private FSNamesystem namesystem;
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -1510,7 +1510,7 @@
|
||||||
<REPLICATION>1</REPLICATION>
|
<REPLICATION>1</REPLICATION>
|
||||||
<MTIME>1512607204120</MTIME>
|
<MTIME>1512607204120</MTIME>
|
||||||
<ATIME>1512607204120</ATIME>
|
<ATIME>1512607204120</ATIME>
|
||||||
<BLOCKSIZE>512</BLOCKSIZE>
|
<BLOCKSIZE>1048576</BLOCKSIZE>
|
||||||
<CLIENT_NAME>DFSClient_NONMAPREDUCE_-923924783_1</CLIENT_NAME>
|
<CLIENT_NAME>DFSClient_NONMAPREDUCE_-923924783_1</CLIENT_NAME>
|
||||||
<CLIENT_MACHINE>127.0.0.1</CLIENT_MACHINE>
|
<CLIENT_MACHINE>127.0.0.1</CLIENT_MACHINE>
|
||||||
<OVERWRITE>true</OVERWRITE>
|
<OVERWRITE>true</OVERWRITE>
|
||||||
|
|
Loading…
Reference in New Issue