HDDS-2114. Rename does not preserve non-explicitly created interim directories. Contributed by Lokesh Jain & Istvan Fajth.

This commit is contained in:
Mukul Kumar Singh 2019-09-17 10:47:00 +05:30
parent 2358e53e9c
commit 292bce7908
2 changed files with 44 additions and 5 deletions

View File

@ -375,7 +375,11 @@ public class BasicOzoneFileSystem extends FileSystem {
}
}
RenameIterator iterator = new RenameIterator(src, dst);
return iterator.iterate();
boolean result = iterator.iterate();
if (result) {
createFakeParentDirectory(src);
}
return result;
}
private class DeleteIterator extends OzoneListingIterator {
@ -460,10 +464,7 @@ public class BasicOzoneFileSystem extends FileSystem {
if (result) {
// If this delete operation removes all files/directories from the
// parent direcotry, then an empty parent directory must be created.
Path parent = f.getParent();
if (parent != null && !parent.isRoot()) {
createFakeDirectoryIfNecessary(parent);
}
createFakeParentDirectory(f);
}
return result;
@ -476,6 +477,19 @@ public class BasicOzoneFileSystem extends FileSystem {
* @param f path to the fake parent directory
* @throws IOException
*/
private void createFakeParentDirectory(Path f) throws IOException {
Path parent = f.getParent();
if (parent != null && !parent.isRoot()) {
createFakeDirectoryIfNecessary(parent);
}
}
/**
* Create a fake directory key if it does not already exist.
*
* @param f path to the fake directory
* @throws IOException
*/
private void createFakeDirectoryIfNecessary(Path f) throws IOException {
String key = pathToKey(f);
if (!key.isEmpty() && !o3Exists(f)) {

View File

@ -40,6 +40,7 @@ import org.apache.commons.io.IOUtils;
import org.junit.After;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Rule;
@ -264,6 +265,30 @@ public class TestOzoneFileSystem {
fileStatus2.equals(dir12.toString()));
}
@Test
public void testNonExplicitlyCreatedPathExistsAfterItsLeafsWereRemoved()
throws Exception {
Path source = new Path("/source");
Path interimPath = new Path(source, "interimPath");
Path leafInsideInterimPath = new Path(interimPath, "leaf");
Path target = new Path("/target");
Path leafInTarget = new Path(target, "leaf");
fs.mkdirs(source);
fs.mkdirs(target);
fs.mkdirs(leafInsideInterimPath);
assertTrue(fs.rename(leafInsideInterimPath, leafInTarget));
// after rename listStatus for interimPath should succeed and
// interimPath should have no children
FileStatus[] statuses = fs.listStatus(interimPath);
assertNotNull("liststatus returns a null array", statuses);
assertEquals("Statuses array is not empty", 0, statuses.length);
FileStatus fileStatus = fs.getFileStatus(interimPath);
assertEquals("FileStatus does not point to interimPath",
interimPath.getName(), fileStatus.getPath().getName());
}
private OzoneKeyDetails getKey(Path keyPath, boolean isDirectory)
throws IOException, OzoneClientException {
String key = o3fs.pathToKey(keyPath);