@Test public void testINodeXAttrsLimit() throws Exception { List<XAttr> existingXAttrs = Lists.newArrayListWithCapacity(2); XAttr xAttr1 = (new XAttr.Builder()).setNameSpace(XAttr.NameSpace.USER). setName("a1").setValue(new byte[]{0x31, 0x32, 0x33}).build(); XAttr xAttr2 = (new XAttr.Builder()).setNameSpace(XAttr.NameSpace.USER). setName("a2").setValue(new byte[]{0x31, 0x31, 0x31}).build(); existingXAttrs.add(xAttr1); existingXAttrs.add(xAttr2); XAttr newSystemXAttr = (new XAttr.Builder()). setNameSpace(XAttr.NameSpace.SYSTEM).setName("a3"). setValue(new byte[]{0x33, 0x33, 0x33}).build(); XAttr newRawXAttr = (new XAttr.Builder()).setNameSpace(XAttr.NameSpace.RAW). setName("a3").setValue(new byte[]{0x33, 0x33, 0x33}).build(); List<XAttr> newXAttrs = Lists.newArrayListWithCapacity(2); newXAttrs.add(newSystemXAttr); newXAttrs.add(newRawXAttr); List<XAttr> xAttrs = fsdir.setINodeXAttrs(existingXAttrs, newXAttrs, EnumSet.of(XAttrSetFlag.CREATE, XAttrSetFlag.REPLACE)); assertEquals(xAttrs.size(), 4); XAttr newXAttr1 = (new XAttr.Builder()).setNameSpace( XAttr.NameSpace.TRUSTED).setName("a4"). setValue(new byte[]{0x34, 0x34, 0x34}).build(); newXAttrs.set(0, newXAttr1); try { fsdir.setINodeXAttrs(existingXAttrs, newXAttrs, EnumSet.of(XAttrSetFlag.CREATE, XAttrSetFlag.REPLACE)); fail("Setting user visible xattr on inode should fail if " + "reaching limit."); } catch (IOException e) { GenericTestUtils.assertExceptionContains("Cannot add additional XAttr " + "to inode, would exceed limit", e); } }
List<XAttr> setINodeXAttrs(final List<XAttr> existingXAttrs, final List<XAttr> toSet, final EnumSet<XAttrSetFlag> flag) throws IOException { for (int i = 0; i < toSet.size(); i++) { for (int j = i + 1; j < toSet.size(); j++) { if (toSet.get(i).equalsIgnoreValue(toSet.get(j))) { throw new IOException("Cannot specify the same XAttr to be set " + "more than once"); } } } int userVisibleXAttrsNum = 0; int newSize = (existingXAttrs != null) ? existingXAttrs.size() : 0; newSize += toSet.size(); List<XAttr> xAttrs = Lists.newArrayListWithCapacity(newSize); for (XAttr xAttr: toSet) { boolean exist = false; if (existingXAttrs != null) { for (XAttr a : existingXAttrs) { if (a.equalsIgnoreValue(xAttr)) { exist = true; break; } } } XAttrSetFlag.validate(xAttr.getName(), exist, flag); xAttrs.add(xAttr); if (isUserVisible(xAttr)) { userVisibleXAttrsNum++; } } if (existingXAttrs != null) { for (XAttr existing : existingXAttrs) { boolean alreadySet = false; for (XAttr set : toSet) { if (set.equalsIgnoreValue(existing)) { alreadySet = true; break; } } if (!alreadySet) { xAttrs.add(existing); if (isUserVisible(existing)) { userVisibleXAttrsNum++; } } } } if (userVisibleXAttrsNum > inodeXAttrsLimit) { throw new IOException("Cannot add additional XAttr to inode, " + "would exceed limit of " + inodeXAttrsLimit); } return xAttrs; }
FSDirectory implements Closeable { List<XAttr> setINodeXAttrs(final List<XAttr> existingXAttrs, final List<XAttr> toSet, final EnumSet<XAttrSetFlag> flag) throws IOException { for (int i = 0; i < toSet.size(); i++) { for (int j = i + 1; j < toSet.size(); j++) { if (toSet.get(i).equalsIgnoreValue(toSet.get(j))) { throw new IOException("Cannot specify the same XAttr to be set " + "more than once"); } } } int userVisibleXAttrsNum = 0; int newSize = (existingXAttrs != null) ? existingXAttrs.size() : 0; newSize += toSet.size(); List<XAttr> xAttrs = Lists.newArrayListWithCapacity(newSize); for (XAttr xAttr: toSet) { boolean exist = false; if (existingXAttrs != null) { for (XAttr a : existingXAttrs) { if (a.equalsIgnoreValue(xAttr)) { exist = true; break; } } } XAttrSetFlag.validate(xAttr.getName(), exist, flag); xAttrs.add(xAttr); if (isUserVisible(xAttr)) { userVisibleXAttrsNum++; } } if (existingXAttrs != null) { for (XAttr existing : existingXAttrs) { boolean alreadySet = false; for (XAttr set : toSet) { if (set.equalsIgnoreValue(existing)) { alreadySet = true; break; } } if (!alreadySet) { xAttrs.add(existing); if (isUserVisible(existing)) { userVisibleXAttrsNum++; } } } } if (userVisibleXAttrsNum > inodeXAttrsLimit) { throw new IOException("Cannot add additional XAttr to inode, " + "would exceed limit of " + inodeXAttrsLimit); } return xAttrs; } }
FSDirectory implements Closeable { List<XAttr> setINodeXAttrs(final List<XAttr> existingXAttrs, final List<XAttr> toSet, final EnumSet<XAttrSetFlag> flag) throws IOException { for (int i = 0; i < toSet.size(); i++) { for (int j = i + 1; j < toSet.size(); j++) { if (toSet.get(i).equalsIgnoreValue(toSet.get(j))) { throw new IOException("Cannot specify the same XAttr to be set " + "more than once"); } } } int userVisibleXAttrsNum = 0; int newSize = (existingXAttrs != null) ? existingXAttrs.size() : 0; newSize += toSet.size(); List<XAttr> xAttrs = Lists.newArrayListWithCapacity(newSize); for (XAttr xAttr: toSet) { boolean exist = false; if (existingXAttrs != null) { for (XAttr a : existingXAttrs) { if (a.equalsIgnoreValue(xAttr)) { exist = true; break; } } } XAttrSetFlag.validate(xAttr.getName(), exist, flag); xAttrs.add(xAttr); if (isUserVisible(xAttr)) { userVisibleXAttrsNum++; } } if (existingXAttrs != null) { for (XAttr existing : existingXAttrs) { boolean alreadySet = false; for (XAttr set : toSet) { if (set.equalsIgnoreValue(existing)) { alreadySet = true; break; } } if (!alreadySet) { xAttrs.add(existing); if (isUserVisible(existing)) { userVisibleXAttrsNum++; } } } } if (userVisibleXAttrsNum > inodeXAttrsLimit) { throw new IOException("Cannot add additional XAttr to inode, " + "would exceed limit of " + inodeXAttrsLimit); } return xAttrs; } FSDirectory(FSNamesystem ns, Configuration conf); }
FSDirectory implements Closeable { List<XAttr> setINodeXAttrs(final List<XAttr> existingXAttrs, final List<XAttr> toSet, final EnumSet<XAttrSetFlag> flag) throws IOException { for (int i = 0; i < toSet.size(); i++) { for (int j = i + 1; j < toSet.size(); j++) { if (toSet.get(i).equalsIgnoreValue(toSet.get(j))) { throw new IOException("Cannot specify the same XAttr to be set " + "more than once"); } } } int userVisibleXAttrsNum = 0; int newSize = (existingXAttrs != null) ? existingXAttrs.size() : 0; newSize += toSet.size(); List<XAttr> xAttrs = Lists.newArrayListWithCapacity(newSize); for (XAttr xAttr: toSet) { boolean exist = false; if (existingXAttrs != null) { for (XAttr a : existingXAttrs) { if (a.equalsIgnoreValue(xAttr)) { exist = true; break; } } } XAttrSetFlag.validate(xAttr.getName(), exist, flag); xAttrs.add(xAttr); if (isUserVisible(xAttr)) { userVisibleXAttrsNum++; } } if (existingXAttrs != null) { for (XAttr existing : existingXAttrs) { boolean alreadySet = false; for (XAttr set : toSet) { if (set.equalsIgnoreValue(existing)) { alreadySet = true; break; } } if (!alreadySet) { xAttrs.add(existing); if (isUserVisible(existing)) { userVisibleXAttrsNum++; } } } } if (userVisibleXAttrsNum > inodeXAttrsLimit) { throw new IOException("Cannot add additional XAttr to inode, " + "would exceed limit of " + inodeXAttrsLimit); } return xAttrs; } FSDirectory(FSNamesystem ns, Configuration conf); int getReadHoldCount(); int getWriteHoldCount(); INodeDirectory getRoot(); @Override void close(); INode getINode(String src); INodesInPath getLastINodeInPath(String src); INodesInPath getINodesInPath4Write(String src
      ); INode getINode4Write(String src); @VisibleForTesting long getYieldCount(); INodeMap getINodeMap(); final void addToInodeMap(INode inode); final void addRootDirToEncryptionZone(XAttrFeature xaf); final void removeFromInodeMap(List<? extends INode> inodes); INode getInode(long id); static byte[][] getPathComponents(INode inode); static boolean isReservedName(INode inode); static boolean isReservedName(String src); }
FSDirectory implements Closeable { List<XAttr> setINodeXAttrs(final List<XAttr> existingXAttrs, final List<XAttr> toSet, final EnumSet<XAttrSetFlag> flag) throws IOException { for (int i = 0; i < toSet.size(); i++) { for (int j = i + 1; j < toSet.size(); j++) { if (toSet.get(i).equalsIgnoreValue(toSet.get(j))) { throw new IOException("Cannot specify the same XAttr to be set " + "more than once"); } } } int userVisibleXAttrsNum = 0; int newSize = (existingXAttrs != null) ? existingXAttrs.size() : 0; newSize += toSet.size(); List<XAttr> xAttrs = Lists.newArrayListWithCapacity(newSize); for (XAttr xAttr: toSet) { boolean exist = false; if (existingXAttrs != null) { for (XAttr a : existingXAttrs) { if (a.equalsIgnoreValue(xAttr)) { exist = true; break; } } } XAttrSetFlag.validate(xAttr.getName(), exist, flag); xAttrs.add(xAttr); if (isUserVisible(xAttr)) { userVisibleXAttrsNum++; } } if (existingXAttrs != null) { for (XAttr existing : existingXAttrs) { boolean alreadySet = false; for (XAttr set : toSet) { if (set.equalsIgnoreValue(existing)) { alreadySet = true; break; } } if (!alreadySet) { xAttrs.add(existing); if (isUserVisible(existing)) { userVisibleXAttrsNum++; } } } } if (userVisibleXAttrsNum > inodeXAttrsLimit) { throw new IOException("Cannot add additional XAttr to inode, " + "would exceed limit of " + inodeXAttrsLimit); } return xAttrs; } FSDirectory(FSNamesystem ns, Configuration conf); int getReadHoldCount(); int getWriteHoldCount(); INodeDirectory getRoot(); @Override void close(); INode getINode(String src); INodesInPath getLastINodeInPath(String src); INodesInPath getINodesInPath4Write(String src
      ); INode getINode4Write(String src); @VisibleForTesting long getYieldCount(); INodeMap getINodeMap(); final void addToInodeMap(INode inode); final void addRootDirToEncryptionZone(XAttrFeature xaf); final void removeFromInodeMap(List<? extends INode> inodes); INode getInode(long id); static byte[][] getPathComponents(INode inode); static boolean isReservedName(INode inode); static boolean isReservedName(String src); final static String DOT_RESERVED_STRING; final static String DOT_RESERVED_PATH_PREFIX; final static byte[] DOT_RESERVED; final static String DOT_INODES_STRING; final static byte[] DOT_INODES; @VisibleForTesting
  final EncryptionZoneManager ezManager; }