blob: 82aa214bf7436a35953de2badfdf91a92c959f75 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hdfs.server.namenode;
import java.util.List;
import org.apache.hadoop.fs.permission.AclEntry;
import org.apache.hadoop.fs.permission.AclEntryScope;
import org.apache.hadoop.fs.permission.AclEntryType;
import org.apache.hadoop.fs.permission.FsAction;
import org.apache.hadoop.hdfs.util.LongBitFormat;
import com.google.common.collect.ImmutableList;
/**
* Class to pack an AclEntry into an integer. <br>
* An ACL entry is represented by a 32-bit integer in Big Endian format. <br>
* The bits can be divided in four segments: <br>
* [0:1) || [1:3) || [3:6) || [6:7) || [7:32) <br>
* <br>
* [0:1) -- the scope of the entry (AclEntryScope) <br>
* [1:3) -- the type of the entry (AclEntryType) <br>
* [3:6) -- the permission of the entry (FsAction) <br>
* [6:7) -- A flag to indicate whether Named entry or not <br>
* [7:32) -- the name of the entry, which is an ID that points to a <br>
* string in the StringTableSection. <br>
*/
public enum AclEntryStatusFormat {
SCOPE(null, 1),
TYPE(SCOPE.BITS, 2),
PERMISSION(TYPE.BITS, 3),
NAMED_ENTRY_CHECK(PERMISSION.BITS, 1),
NAME(NAMED_ENTRY_CHECK.BITS, 25);
private final LongBitFormat BITS;
private AclEntryStatusFormat(LongBitFormat previous, int length) {
BITS = new LongBitFormat(name(), previous, length, 0);
}
static AclEntryScope getScope(int aclEntry) {
int ordinal = (int) SCOPE.BITS.retrieve(aclEntry);
return AclEntryScope.values()[ordinal];
}
static AclEntryType getType(int aclEntry) {
int ordinal = (int) TYPE.BITS.retrieve(aclEntry);
return AclEntryType.values()[ordinal];
}
static FsAction getPermission(int aclEntry) {
int ordinal = (int) PERMISSION.BITS.retrieve(aclEntry);
return FsAction.values()[ordinal];
}
static String getName(int aclEntry) {
int nameExists = (int) NAMED_ENTRY_CHECK.BITS.retrieve(aclEntry);
if (nameExists == 0) {
return null;
}
int id = (int) NAME.BITS.retrieve(aclEntry);
AclEntryType type = getType(aclEntry);
if (type == AclEntryType.USER) {
return SerialNumberManager.INSTANCE.getUser(id);
} else if (type == AclEntryType.GROUP) {
return SerialNumberManager.INSTANCE.getGroup(id);
}
return null;
}
static int toInt(AclEntry aclEntry) {
long aclEntryInt = 0;
aclEntryInt = SCOPE.BITS
.combine(aclEntry.getScope().ordinal(), aclEntryInt);
aclEntryInt = TYPE.BITS.combine(aclEntry.getType().ordinal(), aclEntryInt);
aclEntryInt = PERMISSION.BITS.combine(aclEntry.getPermission().ordinal(),
aclEntryInt);
if (aclEntry.getName() != null) {
aclEntryInt = NAMED_ENTRY_CHECK.BITS.combine(1, aclEntryInt);
if (aclEntry.getType() == AclEntryType.USER) {
int userId = SerialNumberManager.INSTANCE.getUserSerialNumber(aclEntry
.getName());
aclEntryInt = NAME.BITS.combine(userId, aclEntryInt);
} else if (aclEntry.getType() == AclEntryType.GROUP) {
int groupId = SerialNumberManager.INSTANCE
.getGroupSerialNumber(aclEntry.getName());
aclEntryInt = NAME.BITS.combine(groupId, aclEntryInt);
}
}
return (int) aclEntryInt;
}
static AclEntry toAclEntry(int aclEntry) {
AclEntry.Builder builder = new AclEntry.Builder();
builder.setScope(getScope(aclEntry)).setType(getType(aclEntry))
.setPermission(getPermission(aclEntry));
if (getName(aclEntry) != null) {
builder.setName(getName(aclEntry));
}
return builder.build();
}
public static int[] toInt(List<AclEntry> aclEntries) {
int[] entries = new int[aclEntries.size()];
for (int i = 0; i < entries.length; i++) {
entries[i] = toInt(aclEntries.get(i));
}
return entries;
}
public static ImmutableList<AclEntry> toAclEntries(int[] entries) {
ImmutableList.Builder<AclEntry> b = new ImmutableList.Builder<AclEntry>();
for (int entry : entries) {
AclEntry aclEntry = toAclEntry(entry);
b.add(aclEntry);
}
return b.build();
}
}