|
@@ -41,6 +41,7 @@ import org.apache.hadoop.fs.CreateFlag;
|
|
|
import org.apache.hadoop.fs.FSDataInputStream;
|
|
|
import org.apache.hadoop.fs.FSDataOutputStream;
|
|
|
import org.apache.hadoop.fs.FSLinkResolver;
|
|
|
+import org.apache.hadoop.fs.FileAlreadyExistsException;
|
|
|
import org.apache.hadoop.fs.FileChecksum;
|
|
|
import org.apache.hadoop.fs.FileEncryptionInfo;
|
|
|
import org.apache.hadoop.fs.FileStatus;
|
|
@@ -2306,6 +2307,70 @@ public class DistributedFileSystem extends FileSystem
|
|
|
}.resolve(this, absF);
|
|
|
}
|
|
|
|
|
|
+ /* HDFS only */
|
|
|
+ public void provisionEZTrash(final Path path,
|
|
|
+ final FsPermission trashPermission) throws IOException {
|
|
|
+ Path absF = fixRelativePart(path);
|
|
|
+ new FileSystemLinkResolver<Void>() {
|
|
|
+ @Override
|
|
|
+ public Void doCall(Path p) throws IOException {
|
|
|
+ provisionEZTrash(getPathName(p), trashPermission);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Void next(FileSystem fs, Path p) throws IOException {
|
|
|
+ if (fs instanceof DistributedFileSystem) {
|
|
|
+ DistributedFileSystem myDfs = (DistributedFileSystem)fs;
|
|
|
+ myDfs.provisionEZTrash(p, trashPermission);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ throw new UnsupportedOperationException("Cannot provisionEZTrash " +
|
|
|
+ "through a symlink to a non-DistributedFileSystem: " + fs + " -> "
|
|
|
+ + p);
|
|
|
+ }
|
|
|
+ }.resolve(this, absF);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void provisionEZTrash(String path, FsPermission trashPermission)
|
|
|
+ throws IOException {
|
|
|
+ // make sure the path is an EZ
|
|
|
+ EncryptionZone ez = dfs.getEZForPath(path);
|
|
|
+ if (ez == null) {
|
|
|
+ throw new IllegalArgumentException(path + " is not an encryption zone.");
|
|
|
+ }
|
|
|
+
|
|
|
+ String ezPath = ez.getPath();
|
|
|
+ if (!path.toString().equals(ezPath)) {
|
|
|
+ throw new IllegalArgumentException(path + " is not the root of an " +
|
|
|
+ "encryption zone. Do you mean " + ez.getPath() + "?");
|
|
|
+ }
|
|
|
+
|
|
|
+ // check if the trash directory exists
|
|
|
+ Path trashPath = new Path(ez.getPath(), FileSystem.TRASH_PREFIX);
|
|
|
+ try {
|
|
|
+ FileStatus trashFileStatus = getFileStatus(trashPath);
|
|
|
+ String errMessage = "Will not provision new trash directory for " +
|
|
|
+ "encryption zone " + ez.getPath() + ". Path already exists.";
|
|
|
+ if (!trashFileStatus.isDirectory()) {
|
|
|
+ errMessage += "\r\n" +
|
|
|
+ "Warning: " + trashPath.toString() + " is not a directory";
|
|
|
+ }
|
|
|
+ if (!trashFileStatus.getPermission().equals(trashPermission)) {
|
|
|
+ errMessage += "\r\n" +
|
|
|
+ "Warning: the permission of " +
|
|
|
+ trashPath.toString() + " is not " + trashPermission;
|
|
|
+ }
|
|
|
+ throw new FileAlreadyExistsException(errMessage);
|
|
|
+ } catch (FileNotFoundException ignored) {
|
|
|
+ // no trash path
|
|
|
+ }
|
|
|
+
|
|
|
+ // Update the permission bits
|
|
|
+ mkdir(trashPath, trashPermission);
|
|
|
+ setPermission(trashPath, trashPermission);
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void setXAttr(Path path, final String name, final byte[] value,
|
|
|
final EnumSet<XAttrSetFlag> flag) throws IOException {
|