Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.apache.hadoop.fs.PathIsNotEmptyDirectoryException;
import org.apache.hadoop.fs.Trash;
import org.apache.hadoop.fs.contract.ContractTestUtils;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.ozone.MiniOzoneCluster;
import org.apache.hadoop.ozone.OzoneConsts;
Expand Down Expand Up @@ -279,6 +280,7 @@ public void testFileSystem() throws Exception {
testRenameDestinationParentDoesntExist();
testRenameToParentDir();
testSeekOnFileLength();
testAllocateMoreThanOneBlock();
testDeleteRoot();

testRecursiveDelete();
Expand Down Expand Up @@ -585,6 +587,7 @@ protected void testListStatusOnRoot() throws Exception {
*/
protected void testListStatusOnLargeDirectory() throws Exception {
Path root = new Path("/");
deleteRootDir(); // cleanup
Set<String> paths = new TreeSet<>();
int numDirs = 5111;
for(int i = 0; i < numDirs; i++) {
Expand All @@ -595,6 +598,21 @@ protected void testListStatusOnLargeDirectory() throws Exception {
}

FileStatus[] fileStatuses = o3fs.listStatus(root);
// Added logs for debugging failures, to check any sub-path mismatches.
Set<String> actualPaths = new TreeSet<>();
ArrayList<String> actualPathList = new ArrayList<>();
if (rootItemCount != fileStatuses.length) {
for (int i = 0; i < fileStatuses.length; i++) {
actualPaths.add(fileStatuses[i].getPath().getName());
actualPathList.add(fileStatuses[i].getPath().getName());
}
if (rootItemCount != actualPathList.size()) {
actualPaths.removeAll(paths);
actualPathList.removeAll(paths);
LOG.info("actualPaths: {}", actualPaths);
LOG.info("actualPathList: {}", actualPathList);
}
}
assertEquals(
"Total directories listed do not match the existing directories",
rootItemCount, fileStatuses.length);
Expand All @@ -604,6 +622,31 @@ protected void testListStatusOnLargeDirectory() throws Exception {
}
}

/**
* Cleanup files and directories.
*
* @throws IOException DB failure
*/
protected void deleteRootDir() throws IOException {
Path root = new Path("/");
FileStatus[] fileStatuses = fs.listStatus(root);

rootItemCount = 0; // reset to zero

if (fileStatuses == null) {
return;
}

for (FileStatus fStatus : fileStatuses) {
fs.delete(fStatus.getPath(), true);
}

fileStatuses = fs.listStatus(root);
if (fileStatuses != null) {
Assert.assertEquals("Delete root failed!", 0, fileStatuses.length);
}
}

/**
* Tests listStatus on a path with subdirs.
*/
Expand Down Expand Up @@ -662,6 +705,38 @@ public void testSeekOnFileLength() throws IOException {
}
}

public void testAllocateMoreThanOneBlock() throws IOException {
Path file = new Path("/file");
String str = "TestOzoneFileSystemV1.testSeekOnFileLength";
byte[] strBytes = str.getBytes();
long numBlockAllocationsOrg =
cluster.getOzoneManager().getMetrics().getNumBlockAllocates();

try (FSDataOutputStream out1 = fs.create(file, FsPermission.getDefault(),
true, 8, (short) 3, 1, null)) {
for (int i = 0; i < 100000; i++) {
out1.write(strBytes);
}
}

try (FSDataInputStream stream = fs.open(file)) {
FileStatus fileStatus = fs.getFileStatus(file);
long blkSize = fileStatus.getBlockSize();
long fileLength = fileStatus.getLen();
Assert.assertTrue("Block allocation should happen",
fileLength > blkSize);

long newNumBlockAllocations =
cluster.getOzoneManager().getMetrics().getNumBlockAllocates();

Assert.assertTrue("Block allocation should happen",
(newNumBlockAllocations > numBlockAllocationsOrg));

stream.seek(fileLength);
assertEquals(-1, stream.read());
}
}

public void testDeleteRoot() throws IOException {
Path dir = new Path("/dir");
fs.mkdirs(dir);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import org.slf4j.LoggerFactory;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.FS_TRASH_INTERVAL_KEY;
Expand Down Expand Up @@ -396,6 +395,9 @@ public void testFileSystem() throws Exception {
testSeekOnFileLength();
deleteRootDir();

testAllocateMoreThanOneBlock();
deleteRootDir();

testFileDelete();
deleteRootDir();

Expand All @@ -406,32 +408,6 @@ public void testFileSystem() throws Exception {
deleteRootDir();
}

/**
* Cleanup files and directories.
*
* @throws IOException DB failure
*/
protected void deleteRootDir() throws IOException {
Path root = new Path("/");
FileStatus[] fileStatuses = fs.listStatus(root);

if (fileStatuses == null) {
return;
}

for (FileStatus fStatus : fileStatuses) {
fs.delete(fStatus.getPath(), true);
}

fileStatuses = fs.listStatus(root);
if (fileStatuses != null) {
Assert.assertEquals("Delete root failed!", 0, fileStatuses.length);
rootItemCount = 0;
return;
}
rootItemCount = 0;
}

@NotNull
@Override
protected OzoneConfiguration getOzoneConfig() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.apache.hadoop.ozone.om.request.file.OMFileCreateRequestV1;
import org.apache.hadoop.ozone.om.request.key.OMKeysDeleteRequest;
import org.apache.hadoop.ozone.om.request.key.OMAllocateBlockRequest;
import org.apache.hadoop.ozone.om.request.key.OMAllocateBlockRequestV1;
import org.apache.hadoop.ozone.om.request.key.OMKeyCommitRequest;
import org.apache.hadoop.ozone.om.request.key.OMKeyCommitRequestV1;
import org.apache.hadoop.ozone.om.request.key.OMKeyCreateRequest;
Expand Down Expand Up @@ -138,6 +139,9 @@ public static OMClientRequest createClientRequest(OMRequest omRequest) {
case SetBucketProperty:
return new OMBucketSetPropertyRequest(omRequest);
case AllocateBlock:
if (omLayoutVersionV1) {
return new OMAllocateBlockRequestV1(omRequest);
}
return new OMAllocateBlockRequest(omRequest);
case CreateKey:
return new OMKeyCreateRequest(omRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
pathInfoV1.getLeafNodeName());
dbFileInfo = OMFileRequest.getOmKeyInfoFromFileTable(false,
omMetadataManager, dbFileKey, keyName);
if (dbFileInfo != null) {
ozoneManager.getKeyManager().refresh(dbFileInfo);
}
}

// check if the file or directory already existed in OM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@

import javax.annotation.Nonnull;

import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.KEY_NOT_FOUND;
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.NOT_A_FILE;

/**
* Base class for file requests.
Expand Down Expand Up @@ -851,4 +853,54 @@ private static boolean checkSubFileExists(OmKeyInfo omKeyInfo,
public static boolean isImmediateChild(long parentId, long ancestorId) {
return parentId == ancestorId;
}

/**
* Get parent id for the user given path.
*
* @param bucketId bucket id
* @param pathComponents fie path elements
* @param keyName user given key name
* @param omMetadataManager om metadata manager
* @return lastKnownParentID
* @throws IOException DB failure or parent not exists in DirectoryTable
*/
public static long getParentID(long bucketId, Iterator<Path> pathComponents,
String keyName, OMMetadataManager omMetadataManager) throws IOException {

long lastKnownParentId = bucketId;

// If no sub-dirs then bucketID is the root/parent.
if(!pathComponents.hasNext()){
return bucketId;
}

OmDirectoryInfo omDirectoryInfo;
while (pathComponents.hasNext()) {
String nodeName = pathComponents.next().toString();
boolean reachedLastPathComponent = !pathComponents.hasNext();
String dbNodeName =
omMetadataManager.getOzonePathKey(lastKnownParentId, nodeName);

omDirectoryInfo = omMetadataManager.
getDirectoryTable().get(dbNodeName);
if (omDirectoryInfo != null) {
if (reachedLastPathComponent) {
throw new OMException("Can not create file: " + keyName +
" as there is already directory in the given path",
NOT_A_FILE);
}
lastKnownParentId = omDirectoryInfo.getObjectID();
} else {
// One of the sub-dir doesn't exists in DB. Immediate parent should
// exists for committing the key, otherwise will fail the operation.
if (!reachedLastPathComponent) {
throw new OMException("Failed to find parent directory of "
+ keyName + " in DirectoryTable", KEY_NOT_FOUND);
}
break;
}
}

return lastKnownParentId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,13 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
omMetadataManager.getOpenKeyTable().addCacheEntry(
new CacheKey<>(openKeyName),
new CacheValue<>(Optional.of(openKeyInfo), trxnLogIndex));

omBucketInfo.incrUsedBytes(preAllocatedSpace);

omResponse.setAllocateBlockResponse(AllocateBlockResponse.newBuilder()
.setKeyLocation(blockLocation).build());

omClientResponse = new OMAllocateBlockResponse(omResponse.build(),
openKeyInfo, clientID, omVolumeArgs, omBucketInfo.copyObject());

LOG.debug("Allocated block for Volume:{}, Bucket:{}, OpenKey:{}",
volumeName, bucketName, openKeyName);
} catch (IOException ex) {
Expand Down
Loading