HDFS-5849. Removing ACL from an inode fails if it has only a default ACL. Contributed by Chris Nauroth.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-4685@1563205 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7a03dc0482
commit
c654c2e8b9
|
@ -67,3 +67,6 @@ HDFS-4685 (Unreleased)
|
||||||
|
|
||||||
HADOOP-10277. setfacl -x fails to parse ACL spec if trying to remove the
|
HADOOP-10277. setfacl -x fails to parse ACL spec if trying to remove the
|
||||||
mask entry. (Vinay via cnauroth)
|
mask entry. (Vinay via cnauroth)
|
||||||
|
|
||||||
|
HDFS-5849. Removing ACL from an inode fails if it has only a default ACL.
|
||||||
|
(cnauroth)
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
import org.apache.hadoop.fs.permission.AclEntry;
|
import org.apache.hadoop.fs.permission.AclEntry;
|
||||||
import org.apache.hadoop.fs.permission.AclEntryScope;
|
import org.apache.hadoop.fs.permission.AclEntryScope;
|
||||||
import org.apache.hadoop.fs.permission.AclEntryType;
|
import org.apache.hadoop.fs.permission.AclEntryType;
|
||||||
|
import org.apache.hadoop.fs.permission.FsAction;
|
||||||
import org.apache.hadoop.fs.permission.FsPermission;
|
import org.apache.hadoop.fs.permission.FsPermission;
|
||||||
import org.apache.hadoop.hdfs.protocol.AclException;
|
import org.apache.hadoop.hdfs.protocol.AclException;
|
||||||
import org.apache.hadoop.hdfs.protocol.QuotaExceededException;
|
import org.apache.hadoop.hdfs.protocol.QuotaExceededException;
|
||||||
|
@ -157,22 +158,27 @@ final class AclStorage {
|
||||||
int snapshotId) throws QuotaExceededException {
|
int snapshotId) throws QuotaExceededException {
|
||||||
FsPermission perm = inode.getPermissionStatus(snapshotId).getPermission();
|
FsPermission perm = inode.getPermissionStatus(snapshotId).getPermission();
|
||||||
if (perm.getAclBit()) {
|
if (perm.getAclBit()) {
|
||||||
// Restore group permissions from the feature's entry to permission bits,
|
|
||||||
// overwriting the mask, which is not part of a minimal ACL.
|
|
||||||
List<AclEntry> featureEntries = inode.getAclFeature().getEntries();
|
List<AclEntry> featureEntries = inode.getAclFeature().getEntries();
|
||||||
AclEntry groupEntryKey = new AclEntry.Builder()
|
final FsAction groupPerm;
|
||||||
.setScope(AclEntryScope.ACCESS)
|
if (featureEntries.get(0).getScope() == AclEntryScope.ACCESS) {
|
||||||
.setType(AclEntryType.GROUP)
|
// Restore group permissions from the feature's entry to permission
|
||||||
.build();
|
// bits, overwriting the mask, which is not part of a minimal ACL.
|
||||||
int groupEntryIndex = Collections.binarySearch(featureEntries,
|
AclEntry groupEntryKey = new AclEntry.Builder()
|
||||||
groupEntryKey, AclTransformation.ACL_ENTRY_COMPARATOR);
|
.setScope(AclEntryScope.ACCESS)
|
||||||
assert groupEntryIndex >= 0;
|
.setType(AclEntryType.GROUP)
|
||||||
|
.build();
|
||||||
|
int groupEntryIndex = Collections.binarySearch(featureEntries,
|
||||||
|
groupEntryKey, AclTransformation.ACL_ENTRY_COMPARATOR);
|
||||||
|
assert groupEntryIndex >= 0;
|
||||||
|
groupPerm = featureEntries.get(groupEntryIndex).getPermission();
|
||||||
|
} else {
|
||||||
|
groupPerm = perm.getGroupAction();
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the feature and turn off the ACL bit.
|
// Remove the feature and turn off the ACL bit.
|
||||||
inode.removeAclFeature();
|
inode.removeAclFeature();
|
||||||
FsPermission newPerm = new FsPermission(perm.getUserAction(),
|
FsPermission newPerm = new FsPermission(perm.getUserAction(),
|
||||||
featureEntries.get(groupEntryIndex).getPermission(),
|
groupPerm, perm.getOtherAction(),
|
||||||
perm.getOtherAction(),
|
|
||||||
perm.getStickyBit(), false);
|
perm.getStickyBit(), false);
|
||||||
inode.setPermission(newPerm, snapshotId);
|
inode.setPermission(newPerm, snapshotId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,6 +535,23 @@ public class TestNameNodeAcl {
|
||||||
assertAclFeature(false);
|
assertAclFeature(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveAclOnlyDefault() throws IOException {
|
||||||
|
FileSystem.mkdirs(fs, path, FsPermission.createImmutable((short)0750));
|
||||||
|
List<AclEntry> aclSpec = Lists.newArrayList(
|
||||||
|
aclEntry(ACCESS, USER, ALL),
|
||||||
|
aclEntry(ACCESS, GROUP, READ_EXECUTE),
|
||||||
|
aclEntry(ACCESS, OTHER, NONE),
|
||||||
|
aclEntry(DEFAULT, USER, "foo", ALL));
|
||||||
|
fs.setAcl(path, aclSpec);
|
||||||
|
fs.removeAcl(path);
|
||||||
|
AclStatus s = fs.getAclStatus(path);
|
||||||
|
AclEntry[] returned = s.getEntries().toArray(new AclEntry[0]);
|
||||||
|
assertArrayEquals(new AclEntry[] { }, returned);
|
||||||
|
assertPermission((short)0750);
|
||||||
|
assertAclFeature(false);
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected=FileNotFoundException.class)
|
@Test(expected=FileNotFoundException.class)
|
||||||
public void testRemoveAclPathNotFound() throws IOException {
|
public void testRemoveAclPathNotFound() throws IOException {
|
||||||
// Path has not been created.
|
// Path has not been created.
|
||||||
|
|
Loading…
Reference in New Issue