001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.hadoop.hdfs.server.namenode; 020 021import java.util.List; 022 023import org.apache.hadoop.fs.permission.AclEntry; 024import org.apache.hadoop.fs.permission.AclEntryScope; 025import org.apache.hadoop.fs.permission.AclEntryType; 026import org.apache.hadoop.fs.permission.FsAction; 027import org.apache.hadoop.hdfs.util.LongBitFormat; 028 029import com.google.common.collect.ImmutableList; 030 031/** 032 * Class to pack an AclEntry into an integer. <br> 033 * An ACL entry is represented by a 32-bit integer in Big Endian format. <br> 034 * The bits can be divided in four segments: <br> 035 * [0:1) || [1:3) || [3:6) || [6:7) || [7:32) <br> 036 * <br> 037 * [0:1) -- the scope of the entry (AclEntryScope) <br> 038 * [1:3) -- the type of the entry (AclEntryType) <br> 039 * [3:6) -- the permission of the entry (FsAction) <br> 040 * [6:7) -- A flag to indicate whether Named entry or not <br> 041 * [7:32) -- the name of the entry, which is an ID that points to a <br> 042 * string in the StringTableSection. <br> 043 */ 044public enum AclEntryStatusFormat { 045 046 SCOPE(null, 1), 047 TYPE(SCOPE.BITS, 2), 048 PERMISSION(TYPE.BITS, 3), 049 NAMED_ENTRY_CHECK(PERMISSION.BITS, 1), 050 NAME(NAMED_ENTRY_CHECK.BITS, 25); 051 052 private final LongBitFormat BITS; 053 054 private AclEntryStatusFormat(LongBitFormat previous, int length) { 055 BITS = new LongBitFormat(name(), previous, length, 0); 056 } 057 058 static AclEntryScope getScope(int aclEntry) { 059 int ordinal = (int) SCOPE.BITS.retrieve(aclEntry); 060 return AclEntryScope.values()[ordinal]; 061 } 062 063 static AclEntryType getType(int aclEntry) { 064 int ordinal = (int) TYPE.BITS.retrieve(aclEntry); 065 return AclEntryType.values()[ordinal]; 066 } 067 068 static FsAction getPermission(int aclEntry) { 069 int ordinal = (int) PERMISSION.BITS.retrieve(aclEntry); 070 return FsAction.values()[ordinal]; 071 } 072 073 static String getName(int aclEntry) { 074 int nameExists = (int) NAMED_ENTRY_CHECK.BITS.retrieve(aclEntry); 075 if (nameExists == 0) { 076 return null; 077 } 078 int id = (int) NAME.BITS.retrieve(aclEntry); 079 AclEntryType type = getType(aclEntry); 080 if (type == AclEntryType.USER) { 081 return SerialNumberManager.INSTANCE.getUser(id); 082 } else if (type == AclEntryType.GROUP) { 083 return SerialNumberManager.INSTANCE.getGroup(id); 084 } 085 return null; 086 } 087 088 static int toInt(AclEntry aclEntry) { 089 long aclEntryInt = 0; 090 aclEntryInt = SCOPE.BITS 091 .combine(aclEntry.getScope().ordinal(), aclEntryInt); 092 aclEntryInt = TYPE.BITS.combine(aclEntry.getType().ordinal(), aclEntryInt); 093 aclEntryInt = PERMISSION.BITS.combine(aclEntry.getPermission().ordinal(), 094 aclEntryInt); 095 if (aclEntry.getName() != null) { 096 aclEntryInt = NAMED_ENTRY_CHECK.BITS.combine(1, aclEntryInt); 097 if (aclEntry.getType() == AclEntryType.USER) { 098 int userId = SerialNumberManager.INSTANCE.getUserSerialNumber(aclEntry 099 .getName()); 100 aclEntryInt = NAME.BITS.combine(userId, aclEntryInt); 101 } else if (aclEntry.getType() == AclEntryType.GROUP) { 102 int groupId = SerialNumberManager.INSTANCE 103 .getGroupSerialNumber(aclEntry.getName()); 104 aclEntryInt = NAME.BITS.combine(groupId, aclEntryInt); 105 } 106 } 107 return (int) aclEntryInt; 108 } 109 110 static AclEntry toAclEntry(int aclEntry) { 111 AclEntry.Builder builder = new AclEntry.Builder(); 112 builder.setScope(getScope(aclEntry)).setType(getType(aclEntry)) 113 .setPermission(getPermission(aclEntry)); 114 if (getName(aclEntry) != null) { 115 builder.setName(getName(aclEntry)); 116 } 117 return builder.build(); 118 } 119 120 public static int[] toInt(List<AclEntry> aclEntries) { 121 int[] entries = new int[aclEntries.size()]; 122 for (int i = 0; i < entries.length; i++) { 123 entries[i] = toInt(aclEntries.get(i)); 124 } 125 return entries; 126 } 127 128 public static ImmutableList<AclEntry> toAclEntries(int[] entries) { 129 ImmutableList.Builder<AclEntry> b = new ImmutableList.Builder<AclEntry>(); 130 for (int entry : entries) { 131 AclEntry aclEntry = toAclEntry(entry); 132 b.add(aclEntry); 133 } 134 return b.build(); 135 } 136}