|
@@ -18,271 +18,40 @@
|
|
package org.apache.hadoop.hdfs.protocol;
|
|
package org.apache.hadoop.hdfs.protocol;
|
|
|
|
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
+import java.io.ObjectInputValidation;
|
|
|
|
+import java.io.Serializable;
|
|
import java.net.URI;
|
|
import java.net.URI;
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
import java.util.EnumSet;
|
|
import java.util.EnumSet;
|
|
|
|
+import java.util.Set;
|
|
|
|
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceStability;
|
|
import org.apache.hadoop.classification.InterfaceStability;
|
|
import org.apache.hadoop.fs.FileEncryptionInfo;
|
|
import org.apache.hadoop.fs.FileEncryptionInfo;
|
|
import org.apache.hadoop.fs.FileStatus;
|
|
import org.apache.hadoop.fs.FileStatus;
|
|
|
|
+import org.apache.hadoop.fs.FileStatus.AttrFlags;
|
|
import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
import org.apache.hadoop.hdfs.DFSUtilClient;
|
|
import org.apache.hadoop.hdfs.DFSUtilClient;
|
|
|
|
+import org.apache.hadoop.io.Writable;
|
|
|
|
|
|
-/** Interface that represents the over the wire information for a file.
|
|
|
|
|
|
+/**
|
|
|
|
+ * HDFS metadata for an entity in the filesystem.
|
|
*/
|
|
*/
|
|
@InterfaceAudience.Private
|
|
@InterfaceAudience.Private
|
|
@InterfaceStability.Evolving
|
|
@InterfaceStability.Evolving
|
|
-public class HdfsFileStatus extends FileStatus {
|
|
|
|
-
|
|
|
|
- private static final long serialVersionUID = 0x126eb82a;
|
|
|
|
-
|
|
|
|
- // local name of the inode that's encoded in java UTF8
|
|
|
|
- private byte[] uPath;
|
|
|
|
- private byte[] uSymlink; // symlink target encoded in java UTF8/null
|
|
|
|
- private final long fileId;
|
|
|
|
- private final FileEncryptionInfo feInfo;
|
|
|
|
- private final ErasureCodingPolicy ecPolicy;
|
|
|
|
|
|
+public interface HdfsFileStatus
|
|
|
|
+ extends Writable, Comparable<Object>, Serializable, ObjectInputValidation {
|
|
|
|
|
|
- // Used by dir, not including dot and dotdot. Always zero for a regular file.
|
|
|
|
- private final int childrenNum;
|
|
|
|
- private final byte storagePolicy;
|
|
|
|
|
|
+ byte[] EMPTY_NAME = new byte[0];
|
|
|
|
|
|
- public static final byte[] EMPTY_NAME = new byte[0];
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Set of features potentially active on an instance.
|
|
|
|
- */
|
|
|
|
- public enum Flags {
|
|
|
|
|
|
+ /** Set of features potentially active on an instance. */
|
|
|
|
+ enum Flags {
|
|
HAS_ACL,
|
|
HAS_ACL,
|
|
HAS_CRYPT,
|
|
HAS_CRYPT,
|
|
HAS_EC,
|
|
HAS_EC,
|
|
SNAPSHOT_ENABLED
|
|
SNAPSHOT_ENABLED
|
|
}
|
|
}
|
|
- private final EnumSet<Flags> flags;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Constructor.
|
|
|
|
- * @param length the number of bytes the file has
|
|
|
|
- * @param isdir if the path is a directory
|
|
|
|
- * @param replication the replication factor
|
|
|
|
- * @param blocksize the block size
|
|
|
|
- * @param mtime modification time
|
|
|
|
- * @param atime access time
|
|
|
|
- * @param permission permission
|
|
|
|
- * @param owner the owner of the path
|
|
|
|
- * @param group the group of the path
|
|
|
|
- * @param symlink symlink target encoded in java UTF8 or null
|
|
|
|
- * @param path the local name in java UTF8 encoding the same as that in-memory
|
|
|
|
- * @param fileId the file id
|
|
|
|
- * @param childrenNum the number of children. Used by directory.
|
|
|
|
- * @param feInfo the file's encryption info
|
|
|
|
- * @param storagePolicy ID which specifies storage policy
|
|
|
|
- * @param ecPolicy the erasure coding policy
|
|
|
|
- */
|
|
|
|
- protected HdfsFileStatus(long length, boolean isdir, int replication,
|
|
|
|
- long blocksize, long mtime, long atime,
|
|
|
|
- FsPermission permission, EnumSet<Flags> flags,
|
|
|
|
- String owner, String group,
|
|
|
|
- byte[] symlink, byte[] path, long fileId,
|
|
|
|
- int childrenNum, FileEncryptionInfo feInfo,
|
|
|
|
- byte storagePolicy, ErasureCodingPolicy ecPolicy) {
|
|
|
|
- super(length, isdir, replication, blocksize, mtime,
|
|
|
|
- atime, convert(isdir, symlink != null, permission, flags),
|
|
|
|
- owner, group, null, null,
|
|
|
|
- flags.contains(Flags.HAS_ACL), flags.contains(Flags.HAS_CRYPT),
|
|
|
|
- flags.contains(Flags.HAS_EC));
|
|
|
|
- this.flags = flags;
|
|
|
|
- this.uSymlink = symlink;
|
|
|
|
- this.uPath = path;
|
|
|
|
- this.fileId = fileId;
|
|
|
|
- this.childrenNum = childrenNum;
|
|
|
|
- this.feInfo = feInfo;
|
|
|
|
- this.storagePolicy = storagePolicy;
|
|
|
|
- this.ecPolicy = ecPolicy;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Set redundant flags for compatibility with existing applications.
|
|
|
|
- */
|
|
|
|
- protected static FsPermission convert(boolean isdir, boolean symlink,
|
|
|
|
- FsPermission p, EnumSet<Flags> f) {
|
|
|
|
- if (p instanceof FsPermissionExtension) {
|
|
|
|
- // verify flags are set consistently
|
|
|
|
- assert p.getAclBit() == f.contains(HdfsFileStatus.Flags.HAS_ACL);
|
|
|
|
- assert p.getEncryptedBit() == f.contains(HdfsFileStatus.Flags.HAS_CRYPT);
|
|
|
|
- assert p.getErasureCodedBit() == f.contains(HdfsFileStatus.Flags.HAS_EC);
|
|
|
|
- return p;
|
|
|
|
- }
|
|
|
|
- if (null == p) {
|
|
|
|
- if (isdir) {
|
|
|
|
- p = FsPermission.getDirDefault();
|
|
|
|
- } else if (symlink) {
|
|
|
|
- p = FsPermission.getDefault();
|
|
|
|
- } else {
|
|
|
|
- p = FsPermission.getFileDefault();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return new FsPermissionExtension(p, f.contains(Flags.HAS_ACL),
|
|
|
|
- f.contains(Flags.HAS_CRYPT), f.contains(Flags.HAS_EC));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public boolean isSymlink() {
|
|
|
|
- return uSymlink != null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public boolean hasAcl() {
|
|
|
|
- return flags.contains(Flags.HAS_ACL);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public boolean isEncrypted() {
|
|
|
|
- return flags.contains(Flags.HAS_CRYPT);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public boolean isErasureCoded() {
|
|
|
|
- return flags.contains(Flags.HAS_EC);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Check if the local name is empty.
|
|
|
|
- * @return true if the name is empty
|
|
|
|
- */
|
|
|
|
- public final boolean isEmptyLocalName() {
|
|
|
|
- return uPath.length == 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Get the string representation of the local name.
|
|
|
|
- * @return the local name in string
|
|
|
|
- */
|
|
|
|
- public final String getLocalName() {
|
|
|
|
- return DFSUtilClient.bytes2String(uPath);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Get the Java UTF8 representation of the local name.
|
|
|
|
- * @return the local name in java UTF8
|
|
|
|
- */
|
|
|
|
- public final byte[] getLocalNameInBytes() {
|
|
|
|
- return uPath;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Get the string representation of the full path name.
|
|
|
|
- * @param parent the parent path
|
|
|
|
- * @return the full path in string
|
|
|
|
- */
|
|
|
|
- public final String getFullName(final String parent) {
|
|
|
|
- if (isEmptyLocalName()) {
|
|
|
|
- return parent;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- StringBuilder fullName = new StringBuilder(parent);
|
|
|
|
- if (!parent.endsWith(Path.SEPARATOR)) {
|
|
|
|
- fullName.append(Path.SEPARATOR);
|
|
|
|
- }
|
|
|
|
- fullName.append(getLocalName());
|
|
|
|
- return fullName.toString();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Get the full path.
|
|
|
|
- * @param parent the parent path
|
|
|
|
- * @return the full path
|
|
|
|
- */
|
|
|
|
- public final Path getFullPath(final Path parent) {
|
|
|
|
- if (isEmptyLocalName()) {
|
|
|
|
- return parent;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return new Path(parent, getLocalName());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public Path getSymlink() throws IOException {
|
|
|
|
- if (isSymlink()) {
|
|
|
|
- return new Path(DFSUtilClient.bytes2String(uSymlink));
|
|
|
|
- }
|
|
|
|
- throw new IOException("Path " + getPath() + " is not a symbolic link");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void setSymlink(Path sym) {
|
|
|
|
- uSymlink = DFSUtilClient.string2Bytes(sym.toString());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Opaque referant for the symlink, to be resolved at the client.
|
|
|
|
- */
|
|
|
|
- public final byte[] getSymlinkInBytes() {
|
|
|
|
- return uSymlink;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public final long getFileId() {
|
|
|
|
- return fileId;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public final FileEncryptionInfo getFileEncryptionInfo() {
|
|
|
|
- return feInfo;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Get the erasure coding policy if it's set.
|
|
|
|
- * @return the erasure coding policy
|
|
|
|
- */
|
|
|
|
- public ErasureCodingPolicy getErasureCodingPolicy() {
|
|
|
|
- return ecPolicy;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public final int getChildrenNum() {
|
|
|
|
- return childrenNum;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /** @return the storage policy id */
|
|
|
|
- public final byte getStoragePolicy() {
|
|
|
|
- return storagePolicy;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Check if directory is Snapshot enabled or not.
|
|
|
|
- *
|
|
|
|
- * @return true if directory is snapshot enabled
|
|
|
|
- */
|
|
|
|
- public boolean isSnapshotEnabled() {
|
|
|
|
- return flags.contains(Flags.SNAPSHOT_ENABLED);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public boolean equals(Object o) {
|
|
|
|
- // satisfy findbugs
|
|
|
|
- return super.equals(o);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public int hashCode() {
|
|
|
|
- // satisfy findbugs
|
|
|
|
- return super.hashCode();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Resolve the short name of the Path given the URI, parent provided. This
|
|
|
|
- * FileStatus reference will not contain a valid Path until it is resolved
|
|
|
|
- * by this method.
|
|
|
|
- * @param defaultUri FileSystem to fully qualify HDFS path.
|
|
|
|
- * @param parent Parent path of this element.
|
|
|
|
- * @return Reference to this instance.
|
|
|
|
- */
|
|
|
|
- public final FileStatus makeQualified(URI defaultUri, Path parent) {
|
|
|
|
- // fully-qualify path
|
|
|
|
- setPath(getFullPath(parent).makeQualified(defaultUri, null));
|
|
|
|
- return this; // API compatibility
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
* Builder class for HdfsFileStatus instances. Note default values for
|
|
* Builder class for HdfsFileStatus instances. Note default values for
|
|
@@ -290,7 +59,7 @@ public class HdfsFileStatus extends FileStatus {
|
|
*/
|
|
*/
|
|
@InterfaceAudience.Private
|
|
@InterfaceAudience.Private
|
|
@InterfaceStability.Unstable
|
|
@InterfaceStability.Unstable
|
|
- public static class Builder {
|
|
|
|
|
|
+ class Builder {
|
|
// Changing default values will affect cases where values are not
|
|
// Changing default values will affect cases where values are not
|
|
// specified. Be careful!
|
|
// specified. Be careful!
|
|
private long length = 0L;
|
|
private long length = 0L;
|
|
@@ -311,6 +80,7 @@ public class HdfsFileStatus extends FileStatus {
|
|
private byte storagePolicy =
|
|
private byte storagePolicy =
|
|
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
|
|
HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED;
|
|
private ErasureCodingPolicy ecPolicy = null;
|
|
private ErasureCodingPolicy ecPolicy = null;
|
|
|
|
+ private LocatedBlocks locations = null;
|
|
|
|
|
|
/**
|
|
/**
|
|
* Set the length of the entity (default = 0).
|
|
* Set the length of the entity (default = 0).
|
|
@@ -489,14 +259,280 @@ public class HdfsFileStatus extends FileStatus {
|
|
return this;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Set the block locations for this entity (default = null).
|
|
|
|
+ * @param locations HDFS locations
|
|
|
|
+ * (see {@link HdfsLocatedFileStatus#makeQualifiedLocated(URI, Path)})
|
|
|
|
+ * @return This Builder instance
|
|
|
|
+ */
|
|
|
|
+ public Builder locations(LocatedBlocks locations) {
|
|
|
|
+ this.locations = locations;
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* @return An {@link HdfsFileStatus} instance from these parameters.
|
|
* @return An {@link HdfsFileStatus} instance from these parameters.
|
|
*/
|
|
*/
|
|
public HdfsFileStatus build() {
|
|
public HdfsFileStatus build() {
|
|
- return new HdfsFileStatus(length, isdir, replication, blocksize,
|
|
|
|
- mtime, atime, permission, flags, owner, group, symlink, path, fileId,
|
|
|
|
- childrenNum, feInfo, storagePolicy, ecPolicy);
|
|
|
|
|
|
+ if (null == locations && !isdir && null == symlink) {
|
|
|
|
+ return new HdfsNamedFileStatus(length, isdir, replication, blocksize,
|
|
|
|
+ mtime, atime, permission, flags, owner, group, symlink, path,
|
|
|
|
+ fileId, childrenNum, feInfo, storagePolicy, ecPolicy);
|
|
|
|
+ }
|
|
|
|
+ return new HdfsLocatedFileStatus(length, isdir, replication, blocksize,
|
|
|
|
+ mtime, atime, permission, flags, owner, group, symlink, path,
|
|
|
|
+ fileId, childrenNum, feInfo, storagePolicy, ecPolicy, locations);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ///////////////////
|
|
|
|
+ // HDFS-specific //
|
|
|
|
+ ///////////////////
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Inode ID for this entity, if a file.
|
|
|
|
+ * @return inode ID.
|
|
|
|
+ */
|
|
|
|
+ long getFileId();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get metadata for encryption, if present.
|
|
|
|
+ * @return the {@link FileEncryptionInfo} for this stream, or null if not
|
|
|
|
+ * encrypted.
|
|
|
|
+ */
|
|
|
|
+ FileEncryptionInfo getFileEncryptionInfo();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Check if the local name is empty.
|
|
|
|
+ * @return true if the name is empty
|
|
|
|
+ */
|
|
|
|
+ default boolean isEmptyLocalName() {
|
|
|
|
+ return getLocalNameInBytes().length == 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get the string representation of the local name.
|
|
|
|
+ * @return the local name in string
|
|
|
|
+ */
|
|
|
|
+ default String getLocalName() {
|
|
|
|
+ return DFSUtilClient.bytes2String(getLocalNameInBytes());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get the Java UTF8 representation of the local name.
|
|
|
|
+ * @return the local name in java UTF8
|
|
|
|
+ */
|
|
|
|
+ byte[] getLocalNameInBytes();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get the string representation of the full path name.
|
|
|
|
+ * @param parent the parent path
|
|
|
|
+ * @return the full path in string
|
|
|
|
+ */
|
|
|
|
+ default String getFullName(String parent) {
|
|
|
|
+ if (isEmptyLocalName()) {
|
|
|
|
+ return parent;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ StringBuilder fullName = new StringBuilder(parent);
|
|
|
|
+ if (!parent.endsWith(Path.SEPARATOR)) {
|
|
|
|
+ fullName.append(Path.SEPARATOR);
|
|
|
|
+ }
|
|
|
|
+ fullName.append(getLocalName());
|
|
|
|
+ return fullName.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get the full path.
|
|
|
|
+ * @param parent the parent path
|
|
|
|
+ * @return the full path
|
|
|
|
+ */
|
|
|
|
+ default Path getFullPath(Path parent) {
|
|
|
|
+ if (isEmptyLocalName()) {
|
|
|
|
+ return parent;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return new Path(parent, getLocalName());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Opaque referant for the symlink, to be resolved at the client.
|
|
|
|
+ */
|
|
|
|
+ byte[] getSymlinkInBytes();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @return number of children for this inode.
|
|
|
|
+ */
|
|
|
|
+ int getChildrenNum();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get the erasure coding policy if it's set.
|
|
|
|
+ * @return the erasure coding policy
|
|
|
|
+ */
|
|
|
|
+ ErasureCodingPolicy getErasureCodingPolicy();
|
|
|
|
+
|
|
|
|
+ /** @return the storage policy id */
|
|
|
|
+ byte getStoragePolicy();
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Resolve the short name of the Path given the URI, parent provided. This
|
|
|
|
+ * FileStatus reference will not contain a valid Path until it is resolved
|
|
|
|
+ * by this method.
|
|
|
|
+ * @param defaultUri FileSystem to fully qualify HDFS path.
|
|
|
|
+ * @param parent Parent path of this element.
|
|
|
|
+ * @return Reference to this instance.
|
|
|
|
+ */
|
|
|
|
+ default FileStatus makeQualified(URI defaultUri, Path parent) {
|
|
|
|
+ // fully-qualify path
|
|
|
|
+ setPath(getFullPath(parent).makeQualified(defaultUri, null));
|
|
|
|
+ return (FileStatus) this; // API compatibility
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ////////////////////////////
|
|
|
|
+ // FileStatus "overrides" //
|
|
|
|
+ ////////////////////////////
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getPath()}.
|
|
|
|
+ */
|
|
|
|
+ Path getPath();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#setPath(Path)}.
|
|
|
|
+ */
|
|
|
|
+ void setPath(Path p);
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getLen()}.
|
|
|
|
+ */
|
|
|
|
+ long getLen();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#isFile()}.
|
|
|
|
+ */
|
|
|
|
+ boolean isFile();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#isDirectory()}.
|
|
|
|
+ */
|
|
|
|
+ boolean isDirectory();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#isDir()}.
|
|
|
|
+ */
|
|
|
|
+ boolean isDir();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#isSymlink()}.
|
|
|
|
+ */
|
|
|
|
+ boolean isSymlink();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getBlockSize()}.
|
|
|
|
+ */
|
|
|
|
+ long getBlockSize();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getReplication()}.
|
|
|
|
+ */
|
|
|
|
+ short getReplication();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getModificationTime()}.
|
|
|
|
+ */
|
|
|
|
+ long getModificationTime();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getAccessTime()}.
|
|
|
|
+ */
|
|
|
|
+ long getAccessTime();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getPermission()}.
|
|
|
|
+ */
|
|
|
|
+ FsPermission getPermission();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#setPermission(FsPermission)}.
|
|
|
|
+ */
|
|
|
|
+ void setPermission(FsPermission permission);
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getOwner()}.
|
|
|
|
+ */
|
|
|
|
+ String getOwner();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#setOwner(String)}.
|
|
|
|
+ */
|
|
|
|
+ void setOwner(String owner);
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getGroup()}.
|
|
|
|
+ */
|
|
|
|
+ String getGroup();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#setGroup(String)}.
|
|
|
|
+ */
|
|
|
|
+ void setGroup(String group);
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#hasAcl()}.
|
|
|
|
+ */
|
|
|
|
+ boolean hasAcl();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#isEncrypted()}.
|
|
|
|
+ */
|
|
|
|
+ boolean isEncrypted();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#isErasureCoded()}.
|
|
|
|
+ */
|
|
|
|
+ boolean isErasureCoded();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#isSnapshotEnabled()}.
|
|
|
|
+ */
|
|
|
|
+ boolean isSnapshotEnabled();
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#getSymlink()}.
|
|
|
|
+ */
|
|
|
|
+ Path getSymlink() throws IOException;
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#setSymlink(Path sym)}.
|
|
|
|
+ */
|
|
|
|
+ void setSymlink(Path sym);
|
|
|
|
+ /**
|
|
|
|
+ * See {@link FileStatus#compareTo(FileStatus)}.
|
|
|
|
+ */
|
|
|
|
+ int compareTo(FileStatus stat);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Set redundant flags for compatibility with existing applications.
|
|
|
|
+ */
|
|
|
|
+ static FsPermission convert(boolean isdir, boolean symlink,
|
|
|
|
+ FsPermission p, Set<Flags> f) {
|
|
|
|
+ if (p instanceof FsPermissionExtension) {
|
|
|
|
+ // verify flags are set consistently
|
|
|
|
+ assert p.getAclBit() == f.contains(HdfsFileStatus.Flags.HAS_ACL);
|
|
|
|
+ assert p.getEncryptedBit() == f.contains(HdfsFileStatus.Flags.HAS_CRYPT);
|
|
|
|
+ assert p.getErasureCodedBit() == f.contains(HdfsFileStatus.Flags.HAS_EC);
|
|
|
|
+ return p;
|
|
|
|
+ }
|
|
|
|
+ if (null == p) {
|
|
|
|
+ if (isdir) {
|
|
|
|
+ p = FsPermission.getDirDefault();
|
|
|
|
+ } else if (symlink) {
|
|
|
|
+ p = FsPermission.getDefault();
|
|
|
|
+ } else {
|
|
|
|
+ p = FsPermission.getFileDefault();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return new FsPermissionExtension(p, f.contains(Flags.HAS_ACL),
|
|
|
|
+ f.contains(Flags.HAS_CRYPT), f.contains(Flags.HAS_EC));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static Set<AttrFlags> convert(Set<Flags> flags) {
|
|
|
|
+ if (flags.isEmpty()) {
|
|
|
|
+ return FileStatus.NONE;
|
|
|
|
+ }
|
|
|
|
+ EnumSet<AttrFlags> attr = EnumSet.noneOf(AttrFlags.class);
|
|
|
|
+ if (flags.contains(Flags.HAS_ACL)) {
|
|
|
|
+ attr.add(AttrFlags.HAS_ACL);
|
|
|
|
+ }
|
|
|
|
+ if (flags.contains(Flags.HAS_EC)) {
|
|
|
|
+ attr.add(AttrFlags.HAS_EC);
|
|
|
|
+ }
|
|
|
|
+ if (flags.contains(Flags.HAS_CRYPT)) {
|
|
|
|
+ attr.add(AttrFlags.HAS_CRYPT);
|
|
|
|
+ }
|
|
|
|
+ if (flags.contains(Flags.SNAPSHOT_ENABLED)) {
|
|
|
|
+ attr.add(AttrFlags.SNAPSHOT_ENABLED);
|
|
}
|
|
}
|
|
|
|
+ return attr;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|