|
@@ -19,6 +19,7 @@ package org.apache.hadoop.hdfs.server.namenode;
|
|
|
|
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
|
|
|
|
|
|
+import com.google.common.annotations.VisibleForTesting;
|
|
import com.google.protobuf.ByteString;
|
|
import com.google.protobuf.ByteString;
|
|
|
|
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
import org.apache.hadoop.classification.InterfaceAudience;
|
|
@@ -27,6 +28,7 @@ import org.apache.hadoop.fs.FileStatus;
|
|
import org.apache.hadoop.fs.FileSystem;
|
|
import org.apache.hadoop.fs.FileSystem;
|
|
import org.apache.hadoop.fs.Options;
|
|
import org.apache.hadoop.fs.Options;
|
|
import org.apache.hadoop.fs.PathHandle;
|
|
import org.apache.hadoop.fs.PathHandle;
|
|
|
|
+import org.apache.hadoop.fs.permission.AclStatus;
|
|
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
|
|
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
|
|
import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.BlockProto;
|
|
import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.BlockProto;
|
|
import org.apache.hadoop.hdfs.server.common.FileRegion;
|
|
import org.apache.hadoop.hdfs.server.common.FileRegion;
|
|
@@ -52,23 +54,38 @@ public class TreePath {
|
|
private final FileStatus stat;
|
|
private final FileStatus stat;
|
|
private final TreeWalk.TreeIterator i;
|
|
private final TreeWalk.TreeIterator i;
|
|
private final FileSystem fs;
|
|
private final FileSystem fs;
|
|
|
|
+ private final AclStatus acls;
|
|
|
|
|
|
- protected TreePath(FileStatus stat, long parentId, TreeWalk.TreeIterator i,
|
|
|
|
- FileSystem fs) {
|
|
|
|
|
|
+ @VisibleForTesting
|
|
|
|
+ public TreePath(FileStatus stat, long parentId, TreeWalk.TreeIterator i) {
|
|
|
|
+ this(stat, parentId, i, null, null);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public TreePath(FileStatus stat, long parentId, TreeWalk.TreeIterator i,
|
|
|
|
+ FileSystem fs, AclStatus acls) {
|
|
this.i = i;
|
|
this.i = i;
|
|
this.stat = stat;
|
|
this.stat = stat;
|
|
this.parentId = parentId;
|
|
this.parentId = parentId;
|
|
this.fs = fs;
|
|
this.fs = fs;
|
|
|
|
+ this.acls = acls;
|
|
}
|
|
}
|
|
|
|
|
|
public FileStatus getFileStatus() {
|
|
public FileStatus getFileStatus() {
|
|
return stat;
|
|
return stat;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public AclStatus getAclStatus() {
|
|
|
|
+ return acls;
|
|
|
|
+ }
|
|
|
|
+
|
|
public long getParentId() {
|
|
public long getParentId() {
|
|
return parentId;
|
|
return parentId;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public TreeWalk.TreeIterator getIterator() {
|
|
|
|
+ return i;
|
|
|
|
+ }
|
|
|
|
+
|
|
public long getId() {
|
|
public long getId() {
|
|
if (id < 0) {
|
|
if (id < 0) {
|
|
throw new IllegalStateException();
|
|
throw new IllegalStateException();
|
|
@@ -76,8 +93,8 @@ public class TreePath {
|
|
return id;
|
|
return id;
|
|
}
|
|
}
|
|
|
|
|
|
- void accept(long id) {
|
|
|
|
- this.id = id;
|
|
|
|
|
|
+ public void accept(long pathId) {
|
|
|
|
+ this.id = pathId;
|
|
i.onAccept(this, id);
|
|
i.onAccept(this, id);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -121,14 +138,14 @@ public class TreePath {
|
|
INode toFile(UGIResolver ugi, BlockResolver blk,
|
|
INode toFile(UGIResolver ugi, BlockResolver blk,
|
|
BlockAliasMap.Writer<FileRegion> out) throws IOException {
|
|
BlockAliasMap.Writer<FileRegion> out) throws IOException {
|
|
final FileStatus s = getFileStatus();
|
|
final FileStatus s = getFileStatus();
|
|
- ugi.addUser(s.getOwner());
|
|
|
|
- ugi.addGroup(s.getGroup());
|
|
|
|
|
|
+ final AclStatus aclStatus = getAclStatus();
|
|
|
|
+ long permissions = ugi.getPermissionsProto(s, aclStatus);
|
|
INodeFile.Builder b = INodeFile.newBuilder()
|
|
INodeFile.Builder b = INodeFile.newBuilder()
|
|
.setReplication(blk.getReplication(s))
|
|
.setReplication(blk.getReplication(s))
|
|
.setModificationTime(s.getModificationTime())
|
|
.setModificationTime(s.getModificationTime())
|
|
.setAccessTime(s.getAccessTime())
|
|
.setAccessTime(s.getAccessTime())
|
|
.setPreferredBlockSize(blk.preferredBlockSize(s))
|
|
.setPreferredBlockSize(blk.preferredBlockSize(s))
|
|
- .setPermission(ugi.resolve(s))
|
|
|
|
|
|
+ .setPermission(permissions)
|
|
.setStoragePolicyID(HdfsConstants.PROVIDED_STORAGE_POLICY_ID);
|
|
.setStoragePolicyID(HdfsConstants.PROVIDED_STORAGE_POLICY_ID);
|
|
|
|
|
|
// pathhandle allows match as long as the file matches exactly.
|
|
// pathhandle allows match as long as the file matches exactly.
|
|
@@ -141,7 +158,11 @@ public class TreePath {
|
|
"Exact path handle not supported by filesystem " + fs.toString());
|
|
"Exact path handle not supported by filesystem " + fs.toString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- // TODO: storage policy should be configurable per path; use BlockResolver
|
|
|
|
|
|
+ if (aclStatus != null) {
|
|
|
|
+ throw new UnsupportedOperationException(
|
|
|
|
+ "ACLs not supported by ImageWriter");
|
|
|
|
+ }
|
|
|
|
+ //TODO: storage policy should be configurable per path; use BlockResolver
|
|
long off = 0L;
|
|
long off = 0L;
|
|
for (BlockProto block : blk.resolve(s)) {
|
|
for (BlockProto block : blk.resolve(s)) {
|
|
b.addBlocks(block);
|
|
b.addBlocks(block);
|
|
@@ -159,13 +180,17 @@ public class TreePath {
|
|
|
|
|
|
INode toDirectory(UGIResolver ugi) {
|
|
INode toDirectory(UGIResolver ugi) {
|
|
final FileStatus s = getFileStatus();
|
|
final FileStatus s = getFileStatus();
|
|
- ugi.addUser(s.getOwner());
|
|
|
|
- ugi.addGroup(s.getGroup());
|
|
|
|
|
|
+ final AclStatus aclStatus = getAclStatus();
|
|
|
|
+ long permissions = ugi.getPermissionsProto(s, aclStatus);
|
|
INodeDirectory.Builder b = INodeDirectory.newBuilder()
|
|
INodeDirectory.Builder b = INodeDirectory.newBuilder()
|
|
.setModificationTime(s.getModificationTime())
|
|
.setModificationTime(s.getModificationTime())
|
|
.setNsQuota(DEFAULT_NAMESPACE_QUOTA)
|
|
.setNsQuota(DEFAULT_NAMESPACE_QUOTA)
|
|
.setDsQuota(DEFAULT_STORAGE_SPACE_QUOTA)
|
|
.setDsQuota(DEFAULT_STORAGE_SPACE_QUOTA)
|
|
- .setPermission(ugi.resolve(s));
|
|
|
|
|
|
+ .setPermission(permissions);
|
|
|
|
+ if (aclStatus != null) {
|
|
|
|
+ throw new UnsupportedOperationException(
|
|
|
|
+ "ACLs not supported by ImageWriter");
|
|
|
|
+ }
|
|
INode.Builder ib = INode.newBuilder()
|
|
INode.Builder ib = INode.newBuilder()
|
|
.setType(INode.Type.DIRECTORY)
|
|
.setType(INode.Type.DIRECTORY)
|
|
.setId(id)
|
|
.setId(id)
|