HADOOP-10887. Add XAttrs to ViewFs and make XAttrs + ViewFileSystem internal dir behavior consistent. Contributed by Stephen Chu.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1612953 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4a8ac21841
commit
f364269fa0
|
@ -44,6 +44,9 @@ Release 2.6.0 - UNRELEASED
|
||||||
|
|
||||||
HADOOP-10855. Allow Text to be read with a known Length. (todd)
|
HADOOP-10855. Allow Text to be read with a known Length. (todd)
|
||||||
|
|
||||||
|
HADOOP-10887. Add XAttrs to ViewFs and make XAttrs + ViewFileSystem
|
||||||
|
internal dir behavior consistent. (Stephen Chu via wang)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
|
|
@ -2498,4 +2498,33 @@ public final class FileContext {
|
||||||
}
|
}
|
||||||
}.resolve(this, absF);
|
}.resolve(this, absF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the xattr names for a file or directory.
|
||||||
|
* Only those xattr names which the logged-in user has permissions to view
|
||||||
|
* are returned.
|
||||||
|
* <p/>
|
||||||
|
* A regular user can only get xattr names for the "user" namespace.
|
||||||
|
* The super user can only get xattr names for "user" and "trusted"
|
||||||
|
* namespaces.
|
||||||
|
* The xattrs of the "security" and "system" namespaces are only
|
||||||
|
* used/exposed internally by/to the FS impl.
|
||||||
|
* <p/>
|
||||||
|
* @see <a href="http://en.wikipedia.org/wiki/Extended_file_attributes">
|
||||||
|
* http://en.wikipedia.org/wiki/Extended_file_attributes</a>
|
||||||
|
*
|
||||||
|
* @param path Path to get extended attributes
|
||||||
|
* @return List<String> of the XAttr names of the file or directory
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public List<String> listXAttrs(Path path) throws IOException {
|
||||||
|
final Path absF = fixRelativePart(path);
|
||||||
|
return new FSLinkResolver<List<String>>() {
|
||||||
|
@Override
|
||||||
|
public List<String> next(final AbstractFileSystem fs, final Path p)
|
||||||
|
throws IOException {
|
||||||
|
return fs.listXAttrs(p);
|
||||||
|
}
|
||||||
|
}.resolve(this, absF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2510,7 +2510,7 @@ public abstract class FileSystem extends Configured implements Closeable {
|
||||||
* http://en.wikipedia.org/wiki/Extended_file_attributes</a>
|
* http://en.wikipedia.org/wiki/Extended_file_attributes</a>
|
||||||
*
|
*
|
||||||
* @param path Path to get extended attributes
|
* @param path Path to get extended attributes
|
||||||
* @return Map<String, byte[]> describing the XAttrs of the file or directory
|
* @return List<String> of the XAttr names of the file or directory
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public List<String> listXAttrs(Path path) throws IOException {
|
public List<String> listXAttrs(Path path) throws IOException {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.classification.InterfaceStability;
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
|
@ -37,6 +38,7 @@ import org.apache.hadoop.fs.FsStatus;
|
||||||
import org.apache.hadoop.fs.Options.ChecksumOpt;
|
import org.apache.hadoop.fs.Options.ChecksumOpt;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.UnresolvedLinkException;
|
import org.apache.hadoop.fs.UnresolvedLinkException;
|
||||||
|
import org.apache.hadoop.fs.XAttrSetFlag;
|
||||||
import org.apache.hadoop.fs.permission.AclEntry;
|
import org.apache.hadoop.fs.permission.AclEntry;
|
||||||
import org.apache.hadoop.fs.permission.AclStatus;
|
import org.apache.hadoop.fs.permission.AclStatus;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
|
@ -313,6 +315,38 @@ class ChRootedFs extends AbstractFileSystem {
|
||||||
return myFs.getAclStatus(fullPath(path));
|
return myFs.getAclStatus(fullPath(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setXAttr(Path path, String name, byte[] value,
|
||||||
|
EnumSet<XAttrSetFlag> flag) throws IOException {
|
||||||
|
myFs.setXAttr(fullPath(path), name, value, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getXAttr(Path path, String name) throws IOException {
|
||||||
|
return myFs.getXAttr(fullPath(path), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, byte[]> getXAttrs(Path path) throws IOException {
|
||||||
|
return myFs.getXAttrs(fullPath(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, byte[]> getXAttrs(Path path, List<String> names)
|
||||||
|
throws IOException {
|
||||||
|
return myFs.getXAttrs(fullPath(path), names);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> listXAttrs(Path path) throws IOException {
|
||||||
|
return myFs.listXAttrs(fullPath(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeXAttr(Path path, String name) throws IOException {
|
||||||
|
myFs.removeXAttr(fullPath(path), name);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVerifyChecksum(final boolean verifyChecksum)
|
public void setVerifyChecksum(final boolean verifyChecksum)
|
||||||
throws IOException, UnresolvedLinkException {
|
throws IOException, UnresolvedLinkException {
|
||||||
|
|
|
@ -913,5 +913,39 @@ public class ViewFileSystem extends FileSystem {
|
||||||
.addEntries(AclUtil.getMinimalAcl(PERMISSION_555))
|
.addEntries(AclUtil.getMinimalAcl(PERMISSION_555))
|
||||||
.stickyBit(false).build();
|
.stickyBit(false).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setXAttr(Path path, String name, byte[] value,
|
||||||
|
EnumSet<XAttrSetFlag> flag) throws IOException {
|
||||||
|
checkPathIsSlash(path);
|
||||||
|
throw readOnlyMountTable("setXAttr", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getXAttr(Path path, String name) throws IOException {
|
||||||
|
throw new NotInMountpointException(path, "getXAttr");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, byte[]> getXAttrs(Path path) throws IOException {
|
||||||
|
throw new NotInMountpointException(path, "getXAttrs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, byte[]> getXAttrs(Path path, List<String> names)
|
||||||
|
throws IOException {
|
||||||
|
throw new NotInMountpointException(path, "getXAttrs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> listXAttrs(Path path) throws IOException {
|
||||||
|
throw new NotInMountpointException(path, "listXAttrs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeXAttr(Path path, String name) throws IOException {
|
||||||
|
checkPathIsSlash(path);
|
||||||
|
throw readOnlyMountTable("removeXAttr", path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
@ -48,6 +49,7 @@ import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.RemoteIterator;
|
import org.apache.hadoop.fs.RemoteIterator;
|
||||||
import org.apache.hadoop.fs.UnresolvedLinkException;
|
import org.apache.hadoop.fs.UnresolvedLinkException;
|
||||||
import org.apache.hadoop.fs.UnsupportedFileSystemException;
|
import org.apache.hadoop.fs.UnsupportedFileSystemException;
|
||||||
|
import org.apache.hadoop.fs.XAttrSetFlag;
|
||||||
import org.apache.hadoop.fs.local.LocalConfigKeys;
|
import org.apache.hadoop.fs.local.LocalConfigKeys;
|
||||||
import org.apache.hadoop.fs.permission.AclEntry;
|
import org.apache.hadoop.fs.permission.AclEntry;
|
||||||
import org.apache.hadoop.fs.permission.AclUtil;
|
import org.apache.hadoop.fs.permission.AclUtil;
|
||||||
|
@ -652,6 +654,50 @@ public class ViewFs extends AbstractFileSystem {
|
||||||
return res.targetFileSystem.getAclStatus(res.remainingPath);
|
return res.targetFileSystem.getAclStatus(res.remainingPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setXAttr(Path path, String name, byte[] value,
|
||||||
|
EnumSet<XAttrSetFlag> flag) throws IOException {
|
||||||
|
InodeTree.ResolveResult<AbstractFileSystem> res =
|
||||||
|
fsState.resolve(getUriPath(path), true);
|
||||||
|
res.targetFileSystem.setXAttr(res.remainingPath, name, value, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getXAttr(Path path, String name) throws IOException {
|
||||||
|
InodeTree.ResolveResult<AbstractFileSystem> res =
|
||||||
|
fsState.resolve(getUriPath(path), true);
|
||||||
|
return res.targetFileSystem.getXAttr(res.remainingPath, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, byte[]> getXAttrs(Path path) throws IOException {
|
||||||
|
InodeTree.ResolveResult<AbstractFileSystem> res =
|
||||||
|
fsState.resolve(getUriPath(path), true);
|
||||||
|
return res.targetFileSystem.getXAttrs(res.remainingPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, byte[]> getXAttrs(Path path, List<String> names)
|
||||||
|
throws IOException {
|
||||||
|
InodeTree.ResolveResult<AbstractFileSystem> res =
|
||||||
|
fsState.resolve(getUriPath(path), true);
|
||||||
|
return res.targetFileSystem.getXAttrs(res.remainingPath, names);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> listXAttrs(Path path) throws IOException {
|
||||||
|
InodeTree.ResolveResult<AbstractFileSystem> res =
|
||||||
|
fsState.resolve(getUriPath(path), true);
|
||||||
|
return res.targetFileSystem.listXAttrs(res.remainingPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeXAttr(Path path, String name) throws IOException {
|
||||||
|
InodeTree.ResolveResult<AbstractFileSystem> res =
|
||||||
|
fsState.resolve(getUriPath(path), true);
|
||||||
|
res.targetFileSystem.removeXAttr(res.remainingPath, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An instance of this class represents an internal dir of the viewFs
|
* An instance of this class represents an internal dir of the viewFs
|
||||||
|
@ -921,5 +967,39 @@ public class ViewFs extends AbstractFileSystem {
|
||||||
.addEntries(AclUtil.getMinimalAcl(PERMISSION_555))
|
.addEntries(AclUtil.getMinimalAcl(PERMISSION_555))
|
||||||
.stickyBit(false).build();
|
.stickyBit(false).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setXAttr(Path path, String name, byte[] value,
|
||||||
|
EnumSet<XAttrSetFlag> flag) throws IOException {
|
||||||
|
checkPathIsSlash(path);
|
||||||
|
throw readOnlyMountTable("setXAttr", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getXAttr(Path path, String name) throws IOException {
|
||||||
|
throw new NotInMountpointException(path, "getXAttr");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, byte[]> getXAttrs(Path path) throws IOException {
|
||||||
|
throw new NotInMountpointException(path, "getXAttrs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, byte[]> getXAttrs(Path path, List<String> names)
|
||||||
|
throws IOException {
|
||||||
|
throw new NotInMountpointException(path, "getXAttrs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> listXAttrs(Path path) throws IOException {
|
||||||
|
throw new NotInMountpointException(path, "listXAttrs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeXAttr(Path path, String name) throws IOException {
|
||||||
|
checkPathIsSlash(path);
|
||||||
|
throw readOnlyMountTable("removeXAttr", path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -773,4 +773,34 @@ public class ViewFileSystemBaseTest {
|
||||||
assertFalse(aclStatus.isStickyBit());
|
assertFalse(aclStatus.isStickyBit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected=AccessControlException.class)
|
||||||
|
public void testInternalSetXAttr() throws IOException {
|
||||||
|
fsView.setXAttr(new Path("/internalDir"), "xattrName", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=NotInMountpointException.class)
|
||||||
|
public void testInternalGetXAttr() throws IOException {
|
||||||
|
fsView.getXAttr(new Path("/internalDir"), "xattrName");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=NotInMountpointException.class)
|
||||||
|
public void testInternalGetXAttrs() throws IOException {
|
||||||
|
fsView.getXAttrs(new Path("/internalDir"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=NotInMountpointException.class)
|
||||||
|
public void testInternalGetXAttrsWithNames() throws IOException {
|
||||||
|
fsView.getXAttrs(new Path("/internalDir"), new ArrayList<String>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=NotInMountpointException.class)
|
||||||
|
public void testInternalListXAttr() throws IOException {
|
||||||
|
fsView.listXAttrs(new Path("/internalDir"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=AccessControlException.class)
|
||||||
|
public void testInternalRemoveXAttr() throws IOException {
|
||||||
|
fsView.removeXAttr(new Path("/internalDir"), "xattrName");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -747,4 +747,34 @@ public class ViewFsBaseTest {
|
||||||
AclUtil.getMinimalAcl(PERMISSION_555));
|
AclUtil.getMinimalAcl(PERMISSION_555));
|
||||||
assertFalse(aclStatus.isStickyBit());
|
assertFalse(aclStatus.isStickyBit());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected=AccessControlException.class)
|
||||||
|
public void testInternalSetXAttr() throws IOException {
|
||||||
|
fcView.setXAttr(new Path("/internalDir"), "xattrName", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=NotInMountpointException.class)
|
||||||
|
public void testInternalGetXAttr() throws IOException {
|
||||||
|
fcView.getXAttr(new Path("/internalDir"), "xattrName");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=NotInMountpointException.class)
|
||||||
|
public void testInternalGetXAttrs() throws IOException {
|
||||||
|
fcView.getXAttrs(new Path("/internalDir"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=NotInMountpointException.class)
|
||||||
|
public void testInternalGetXAttrsWithNames() throws IOException {
|
||||||
|
fcView.getXAttrs(new Path("/internalDir"), new ArrayList<String>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=NotInMountpointException.class)
|
||||||
|
public void testInternalListXAttr() throws IOException {
|
||||||
|
fcView.listXAttrs(new Path("/internalDir"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected=AccessControlException.class)
|
||||||
|
public void testInternalRemoveXAttr() throws IOException {
|
||||||
|
fcView.removeXAttr(new Path("/internalDir"), "xattrName");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue