aclSp
}
int r = lib.jfs_setfacl(Thread.currentThread().getId(), handle, normalizePath(path), scope.ordinal() + 1, buf,
12 + namedaclsize);
+ if (r == ENOTSUP) {
+ throw new IOException("Invalid ACL: only directories may have a default ACL");
+ }
if (r < 0)
throw error(r, path);
}
diff --git a/sdk/java/src/main/java/io/juicefs/utils/FsPermissionExtension.java b/sdk/java/src/main/java/io/juicefs/utils/FsPermissionExtension.java
new file mode 100644
index 000000000000..c0dee7e0f0df
--- /dev/null
+++ b/sdk/java/src/main/java/io/juicefs/utils/FsPermissionExtension.java
@@ -0,0 +1,63 @@
+/**
+ * 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 io.juicefs.utils;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.fs.permission.FsPermission;
+
+/**
+ * HDFS permission subclass used to indicate an ACL is present and/or that the
+ * underlying file/dir is encrypted. The ACL/encrypted bits are not visible
+ * directly to users of {@link FsPermission} serialization. This is
+ * done for backwards compatibility in case any existing clients assume the
+ * value of FsPermission is in a particular range.
+ */
+@InterfaceAudience.Private
+public class FsPermissionExtension extends FsPermission {
+ private final static short ACL_BIT = 1 << 12;
+ private final static short ENCRYPTED_BIT = 1 << 13;
+ private final boolean aclBit;
+ private final boolean encryptedBit;
+
+ /**
+ * Constructs a new FsPermissionExtension based on the given FsPermission.
+ *
+ * @param perm FsPermission containing permission bits
+ */
+ public FsPermissionExtension(FsPermission perm, boolean hasAcl,
+ boolean isEncrypted) {
+ super(perm.toShort());
+ aclBit = hasAcl;
+ encryptedBit = isEncrypted;
+ }
+
+ @Override
+ public short toExtendedShort() {
+ return (short) (toShort() |
+ (aclBit ? ACL_BIT : 0) | (encryptedBit ? ENCRYPTED_BIT : 0));
+ }
+
+ public boolean getAclBit() {
+ return aclBit;
+ }
+
+ @Override
+ public boolean getEncryptedBit() {
+ return encryptedBit;
+ }
+}
\ No newline at end of file
diff --git a/sdk/java/src/main/java/io/juicefs/utils/ReflectionUtil.java b/sdk/java/src/main/java/io/juicefs/utils/ReflectionUtil.java
new file mode 100644
index 000000000000..418be1736022
--- /dev/null
+++ b/sdk/java/src/main/java/io/juicefs/utils/ReflectionUtil.java
@@ -0,0 +1,53 @@
+/*
+ * JuiceFS, Copyright 2024 Juicedata, Inc.
+ *
+ * Licensed 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 io.juicefs.utils;
+
+import java.lang.reflect.Constructor;
+
+public class ReflectionUtil {
+ public static boolean hasMethod(String className, String method, String[] params) {
+ try {
+ Class>[] classes = null;
+ if (params != null) {
+ classes = new Class[params.length];
+ for (int i = 0; i < params.length; i++) {
+ classes[i] = Class.forName(params[i], false, Thread.currentThread().getContextClassLoader());
+ }
+ }
+ return hasMethod(className, method, classes);
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+ public static boolean hasMethod(String className, String method, Class>[] params) {
+ try {
+ Class> clazz = Class.forName(className, false, Thread.currentThread().getContextClassLoader());
+ clazz.getDeclaredMethod(method, params);
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public static Constructor getConstructor(Class clazz, Class>... params) {
+ try {
+ return clazz.getConstructor(params);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+}
diff --git a/sdk/java/src/test/java/io/juicefs/JuiceFileSystemTest.java b/sdk/java/src/test/java/io/juicefs/JuiceFileSystemTest.java
index eb5cde7f15d1..c9ad0891f9b3 100644
--- a/sdk/java/src/test/java/io/juicefs/JuiceFileSystemTest.java
+++ b/sdk/java/src/test/java/io/juicefs/JuiceFileSystemTest.java
@@ -1100,4 +1100,24 @@ public void testAccessAclNotInherited() throws IOException {
fs.delete(parent, true);
}
+ public void testFileStatusWithAcl() throws Exception {
+ List acls = Lists.newArrayList(
+ aclEntry(ACCESS, USER, ALL),
+ aclEntry(ACCESS, USER, "foo", ALL),
+ aclEntry(ACCESS, OTHER, ALL),
+ aclEntry(ACCESS, GROUP, ALL)
+ );
+ Path p = new Path("/test_acl_status");
+ fs.delete(p, true);
+ fs.mkdirs(p);
+ FileStatus pStatus = fs.getFileStatus(p);
+ assertFalse(pStatus.hasAcl());
+
+ Path f = new Path(p, "f");
+ fs.create(f).close();
+ fs.setAcl(f, acls);
+ FileStatus[] fileStatuses = fs.listStatus(p);
+ assertTrue(fileStatuses[0].getPermission().getAclBit());
+ assertTrue(fileStatuses[0].hasAcl());
+ }
}
diff --git a/sdk/java/src/test/java/io/juicefs/acl/TestAclCLI.java b/sdk/java/src/test/java/io/juicefs/acl/TestAclCLI.java
new file mode 100644
index 000000000000..e03999d5efff
--- /dev/null
+++ b/sdk/java/src/test/java/io/juicefs/acl/TestAclCLI.java
@@ -0,0 +1,79 @@
+/**
+ * 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 io.juicefs.acl;
+
+import org.apache.hadoop.cli.CLITestHelperDFS;
+import org.apache.hadoop.cli.util.CLICommand;
+import org.apache.hadoop.cli.util.CommandExecutor.Result;
+import org.apache.hadoop.hdfs.DFSConfigKeys;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestAclCLI extends CLITestHelperDFS {
+ private String vol = null;
+ private String username = null;
+
+ protected void initConf() {
+ conf.setBoolean(DFSConfigKeys.DFS_NAMENODE_ACLS_ENABLED_KEY, true);
+ conf.setBoolean(
+ DFSConfigKeys.DFS_NAMENODE_POSIX_ACL_INHERITANCE_ENABLED_KEY, false);
+ }
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ initConf();
+ vol = "jfs://dev/";
+ username = System.getProperty("user.name");
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ @Override
+ protected String getTestFile() {
+ return "testAclCLI.xml";
+ }
+
+ @Override
+ protected String expandCommand(final String cmd) {
+ String expCmd = cmd;
+ expCmd = expCmd.replaceAll("NAMENODE", vol);
+ expCmd = expCmd.replaceAll("USERNAME", username);
+ expCmd = expCmd.replaceAll("#LF#",
+ System.getProperty("line.separator"));
+ expCmd = super.expandCommand(expCmd);
+ return expCmd;
+ }
+
+ @Override
+ protected Result execute(CLICommand cmd) throws Exception {
+ return cmd.getExecutor(vol, conf).executeCommand(cmd.getCmd());
+ }
+
+ @Test
+ @Override
+ public void testAll() {
+ super.testAll();
+ }
+}
diff --git a/sdk/java/src/test/resources/testAclCLI.xml b/sdk/java/src/test/resources/testAclCLI.xml
new file mode 100644
index 000000000000..120da68e4f69
--- /dev/null
+++ b/sdk/java/src/test/resources/testAclCLI.xml
@@ -0,0 +1,1075 @@
+
+
+
+
+
+
+
+ test
+
+
+
+
+
+ getfacl: basic permissions
+
+ -fs NAMENODE -touchz /file1
+ -fs NAMENODE -getfacl /file1
+
+
+ -fs NAMENODE -rm /file1
+
+
+
+ SubstringComparator
+ # file: /file1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rw-
+
+
+ SubstringComparator
+ group::r--
+
+
+ SubstringComparator
+ other::r--
+
+
+
+
+ getfacl: basic permissions for directory
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -getfacl /dir1
+
+
+ -fs NAMENODE -rm /dir1
+
+
+
+ SubstringComparator
+ # file: /dir1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rwx
+
+
+ SubstringComparator
+ group::r-x
+
+
+ SubstringComparator
+ other::r-x
+
+
+
+
+ setfacl : Add an ACL
+
+ -fs NAMENODE -touchz /file1
+ -fs NAMENODE -setfacl -m user:bob:r-- /file1
+ -fs NAMENODE -getfacl /file1
+
+
+ -fs NAMENODE -rm /file1
+
+
+
+ SubstringComparator
+ # file: /file1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rw-
+
+
+ SubstringComparator
+ user:bob:r--
+
+
+ SubstringComparator
+ group::r--
+
+
+ SubstringComparator
+ mask::r--
+
+
+ SubstringComparator
+ other::r--
+
+
+
+
+ setfacl : Add multiple ACLs at once
+
+ -fs NAMENODE -touchz /file1
+ -fs NAMENODE -setfacl -m user:bob:r--,group:users:r-x /file1
+ -fs NAMENODE -getfacl /file1
+
+
+ -fs NAMENODE -rm /file1
+
+
+
+ SubstringComparator
+ # file: /file1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rw-
+
+
+ SubstringComparator
+ user:bob:r--
+
+
+ SubstringComparator
+ group::r--
+
+
+ SubstringComparator
+ group:users:r-x
+
+
+ SubstringComparator
+ mask::r-x
+
+
+ SubstringComparator
+ other::r--
+
+
+
+
+ setfacl : Remove an ACL
+
+ -fs NAMENODE -touchz /file1
+ -fs NAMENODE -setfacl -m user:bob:r--,user:charlie:r-x /file1
+ -fs NAMENODE -setfacl -x user:bob /file1
+ -fs NAMENODE -getfacl /file1
+
+
+ -fs NAMENODE -rm /file1
+
+
+
+ SubstringComparator
+ # file: /file1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rw-
+
+
+ SubstringComparator
+ user:charlie:r-x
+
+
+ SubstringComparator
+ group::r--
+
+
+ SubstringComparator
+ other::r--
+
+
+ RegexpAcrossOutputComparator
+ .*(?!bob)*
+
+
+
+
+ setfacl : Add default ACL
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m user:bob:r--,group:users:r-x /dir1
+ -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1
+ -fs NAMENODE -getfacl /dir1
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ SubstringComparator
+ # file: /dir1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rwx
+
+
+ SubstringComparator
+ user:bob:r--
+
+
+ SubstringComparator
+ group::r-x
+
+
+ SubstringComparator
+ group:users:r-x
+
+
+ SubstringComparator
+ mask::r-x
+
+
+ SubstringComparator
+ other::r-x
+
+
+ SubstringComparator
+ default:user::rwx
+
+
+ SubstringComparator
+ default:user:charlie:r-x
+
+
+ SubstringComparator
+ default:group::r-x
+
+
+ SubstringComparator
+ default:group:admin:rwx
+
+
+ SubstringComparator
+ default:mask::rwx
+
+
+ SubstringComparator
+ default:other::r-x
+
+
+
+
+ setfacl : Add minimal default ACL
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m default:user::rwx /dir1
+ -fs NAMENODE -getfacl /dir1
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ SubstringComparator
+ # file: /dir1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rwx
+
+
+ SubstringComparator
+ group::r-x
+
+
+ SubstringComparator
+ other::r-x
+
+
+ SubstringComparator
+ default:user::rwx
+
+
+ SubstringComparator
+ default:group::r-x
+
+
+ SubstringComparator
+ default:other::r-x
+
+
+ RegexpAcrossOutputComparator
+ .*(?!default\:mask)*
+
+
+
+
+ setfacl : try adding default ACL to file
+
+ -fs NAMENODE -touchz /file1
+ -fs NAMENODE -setfacl -m default:user:charlie:r-x /file1
+
+
+ -fs NAMENODE -rm /file1
+
+
+
+ SubstringComparator
+ setfacl: Invalid ACL: only directories may have a default ACL
+
+
+
+
+ setfacl : Remove one default ACL
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m user:bob:r--,group:users:r-x /dir1
+ -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1
+ -fs NAMENODE -setfacl -x default:user:charlie /dir1
+ -fs NAMENODE -getfacl /dir1
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ SubstringComparator
+ # file: /dir1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rwx
+
+
+ SubstringComparator
+ user:bob:r--
+
+
+ SubstringComparator
+ group::r-x
+
+
+ SubstringComparator
+ group:users:r-x
+
+
+ SubstringComparator
+ mask::r-x
+
+
+ SubstringComparator
+ other::r-x
+
+
+ SubstringComparator
+ default:user::rwx
+
+
+ SubstringComparator
+ default:group::r-x
+
+
+ SubstringComparator
+ default:group:admin:rwx
+
+
+ SubstringComparator
+ default:mask::rwx
+
+
+ SubstringComparator
+ default:other::r-x
+
+
+ RegexpAcrossOutputComparator
+ .*(?!default:user:charlie).*
+
+
+
+
+ setfacl : Remove all default ACL
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m user:bob:r--,group:users:r-x /dir1
+ -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1
+ -fs NAMENODE -setfacl -k /dir1
+ -fs NAMENODE -getfacl /dir1
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ SubstringComparator
+ # file: /dir1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rwx
+
+
+ SubstringComparator
+ user:bob:r--
+
+
+ SubstringComparator
+ group::r-x
+
+
+ SubstringComparator
+ group:users:r-x
+
+
+ SubstringComparator
+ mask::r-x
+
+
+ SubstringComparator
+ other::r-x
+
+
+ RegexpAcrossOutputComparator
+ .*(?!default).*
+
+
+
+
+ setfacl : Remove all but base ACLs for a directory
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m user:charlie:r-x,default:group:admin:rwx /dir1
+ -fs NAMENODE -setfacl -b /dir1
+ -fs NAMENODE -getfacl /dir1
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ SubstringComparator
+ # file: /dir1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rwx
+
+
+ SubstringComparator
+ group::r-x
+
+
+ SubstringComparator
+ other::r-x
+
+
+ RegexpAcrossOutputComparator
+ .*(?!charlie).*
+
+
+ RegexpAcrossOutputComparator
+ .*(?!default).*
+
+
+ RegexpAcrossOutputComparator
+ .*(?!admin).*
+
+
+
+
+ setfacl : Remove all but base ACLs for a file
+
+ -fs NAMENODE -touchz /file1
+ -fs NAMENODE -setfacl -m user:charlie:r-x,group:admin:rwx /file1
+ -fs NAMENODE -setfacl -b /file1
+ -fs NAMENODE -getfacl /file1
+
+
+ -fs NAMENODE -rm /file1
+
+
+
+ SubstringComparator
+ # file: /file1
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rw-
+
+
+ SubstringComparator
+ group::r--
+
+
+ SubstringComparator
+ other::r--
+
+
+ RegexpAcrossOutputComparator
+ .*(?!charlie).*
+
+
+ RegexpAcrossOutputComparator
+ .*(?!admin).*
+
+
+
+
+ setfacl : check inherit default ACL to file
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1
+ -fs NAMENODE -touchz /dir1/file
+ -fs NAMENODE -getfacl /dir1/file
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ SubstringComparator
+ # file: /dir1/file
+
+
+ SubstringComparator
+ # owner: USERNAME
+
+
+ SubstringComparator
+ # group: supergroup
+
+
+ SubstringComparator
+ user::rw-
+
+
+ SubstringComparator
+ user:charlie:r-x
+
+
+ SubstringComparator
+ group::r-x
+
+
+ SubstringComparator
+ group:admin:rwx
+
+
+ SubstringComparator
+ mask::rw-
+
+
+ SubstringComparator
+ other::r--
+
+
+ RegexpAcrossOutputComparator
+ .*(?!default).*
+
+
+
+
+ setfacl : check inherit default ACL to dir
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m default:user:charlie:r-x,default:group:admin:rwx /dir1
+ -fs NAMENODE -mkdir /dir1/dir2
+ -fs NAMENODE -getfacl /dir1/dir2
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ ExactLineComparator
+ # file: /dir1/dir2
+
+
+ ExactLineComparator
+ # owner: USERNAME
+
+
+ ExactLineComparator
+ # group: supergroup
+
+
+ ExactLineComparator
+ user::rwx
+
+
+ ExactLineComparator
+ user:charlie:r-x
+
+
+ ExactLineComparator
+ group::r-x
+
+
+ RegexpComparator
+ ^group:admin:rwx\b.*
+
+
+ ExactLineComparator
+ mask::rwx
+
+
+ ExactLineComparator
+ default:user::rwx
+
+
+ ExactLineComparator
+ default:user:charlie:r-x
+
+
+ ExactLineComparator
+ default:group::r-x
+
+
+ ExactLineComparator
+ default:group:admin:rwx
+
+
+ ExactLineComparator
+ default:mask::rwx
+
+
+ ExactLineComparator
+ default:other::r-x
+
+
+ ExactLineComparator
+ other::r-x
+
+
+
+
+ getfacl -R : recursive
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m user:charlie:r-x,group:admin:rwx /dir1
+ -fs NAMENODE -mkdir /dir1/dir2
+ -fs NAMENODE -setfacl -m user:user1:r-x,group:users:rwx /dir1/dir2
+ -fs NAMENODE -getfacl -R /dir1
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ ExactComparator
+ # file: /dir1#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#user:charlie:r-x#LF#group::r-x#LF#group:admin:rwx#LF#mask::rwx#LF#other::r-x#LF##LF## file: /dir1/dir2#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#user:user1:r-x#LF#group::r-x#LF#group:users:rwx#LF#mask::rwx#LF#other::r-x#LF##LF#
+
+
+
+
+ setfacl -R : recursive
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -mkdir /dir1/dir2
+ -fs NAMENODE -setfacl -R -m user:charlie:r-x,group:admin:rwx /dir1
+ -fs NAMENODE -getfacl -R /dir1
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ ExactComparator
+ # file: /dir1#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#user:charlie:r-x#LF#group::r-x#LF#group:admin:rwx#LF#mask::rwx#LF#other::r-x#LF##LF## file: /dir1/dir2#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#user:charlie:r-x#LF#group::r-x#LF#group:admin:rwx#LF#mask::rwx#LF#other::r-x#LF##LF#
+
+
+
+
+ setfacl --set : Set full set of ACLs
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m user:charlie:r-x,group:admin:rwx /dir1
+ -fs NAMENODE -setfacl --set user::rw-,group::r--,other::r--,user:user1:r-x,group:users:rw- /dir1
+ -fs NAMENODE -getfacl /dir1
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ ExactComparator
+ # file: /dir1#LF## owner: USERNAME#LF## group: supergroup#LF#user::rw-#LF#user:user1:r-x#LF#group::r--#LF#group:users:rw-#LF#mask::rwx#LF#other::r--#LF##LF#
+
+
+
+
+ setfacl -x mask : remove mask entry along with other ACL entries
+
+ -fs NAMENODE -mkdir /dir1
+ -fs NAMENODE -setfacl -m user:charlie:r-x,group:admin:rwx /dir1
+ -fs NAMENODE -setfacl -x mask::,user:charlie,group:admin /dir1
+ -fs NAMENODE -getfacl /dir1
+
+
+ -fs NAMENODE -rm -R /dir1
+
+
+
+ ExactComparator
+ # file: /dir1#LF## owner: USERNAME#LF## group: supergroup#LF#user::rwx#LF#group::r-x#LF#other::r-x#LF##LF#
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+