[LTP] [PATCH v5 1/8] fs/acl: Add ACL_USER_OBJ permission test

Sachin Sant sachinp@linux.ibm.com
Mon Jun 8 11:21:53 CEST 2026


Add acl_user_obj01 test to validate ACL_USER_OBJ permissions:
- Owner permissions correctly control file/directory access
- ACL_USER_OBJ=rwx via setxattr() overrides chmod restrictions
- Owner permissions work independently of group/other permissions
- Tests use arbitrary UIDs without requiring actual user creation

The patch also adds acl_lib.h containing shared helpers for ACL
manipulation via xattr API, including:
- ACL structure management (acl_init, acl_free, acl_add_entry)
- ACL serialization/deserialization for kernel xattr format
- ACL get/set operations using getxattr/setxattr
- permission testing and file operations
- Support for both ACCESS and DEFAULT ACL types

The implementation uses direct xattr API (getxattr/setxattr) to
test kernel ACL behavior directly. Tests run on ext2/3/4,
XFS, and Btrfs filesystems with ACL support.

Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Sachin Sant <sachinp@linux.ibm.com>
---
V5 changes:
- Switch to kernel only test validation to remove dependency on libacl
  and useradd/del commands.
- v4 link https://lore.kernel.org/ltp/20260604065417.25924-1-sachinp@linux.ibm.com/T/#t

V4 changes:
- Add -U flag in create_user_if_needed() to useradd for guaranteed
  user-private groups.
- Move EOPNOTSUPP handling into set_acl_file() helper
- v3 link https://lore.kernel.org/ltp/20260603140147.50738-1-sachinp@linux.ibm.com/T/#t

V3 changes:
- Updated copyright header as per LTP format.
- v2 link https://lore.kernel.org/ltp/20260603065744.47106-1-sachinp@linux.ibm.com/T/#t

V2 changes:
- Added reset_test_path_no_chown variant to skip chown step.
 acl_link01 and xattr_test01 tests are updated to use this
 variant.
- Updated acl_user_obj01.c to correct incorrect description
- v1 link https://lore.kernel.org/ltp/20260602121958.27494-1-sachinp@linux.ibm.com/T/#t

V1 changes:
- Use ACL_LIBS variable instead of hardcoded -lacl in Makefile
- Move ACL header includes inside feature guards in acl_lib.h
- Use HAVE_LIBACL guards in .c code
- Report TCONF when libacl is not available
- rfc link https://lore.kernel.org/ltp/477836fd-80c8-4168-bfe6-00b374bb2534@linux.ibm.com/T/#t

---
 runtest/fs                               |   3 +
 testcases/kernel/fs/acl/.gitignore       |   1 +
 testcases/kernel/fs/acl/Makefile         |   8 +
 testcases/kernel/fs/acl/acl_lib.h        | 483 +++++++++++++++++++++++
 testcases/kernel/fs/acl/acl_user_obj01.c | 154 ++++++++
 5 files changed, 649 insertions(+)
 create mode 100644 testcases/kernel/fs/acl/.gitignore
 create mode 100644 testcases/kernel/fs/acl/Makefile
 create mode 100644 testcases/kernel/fs/acl/acl_lib.h
 create mode 100644 testcases/kernel/fs/acl/acl_user_obj01.c

diff --git a/runtest/fs b/runtest/fs
index 1d753e0dd..2a878744b 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -87,3 +87,6 @@ binfmt_misc01 binfmt_misc01.sh
 binfmt_misc02 binfmt_misc02.sh
 
 squashfs01 squashfs01
+
+# Run the acl tests
+acl_user_obj01 acl_user_obj01
diff --git a/testcases/kernel/fs/acl/.gitignore b/testcases/kernel/fs/acl/.gitignore
new file mode 100644
index 000000000..d9c46db11
--- /dev/null
+++ b/testcases/kernel/fs/acl/.gitignore
@@ -0,0 +1 @@
+/acl_user_obj01
diff --git a/testcases/kernel/fs/acl/Makefile b/testcases/kernel/fs/acl/Makefile
new file mode 100644
index 000000000..2d9cba46d
--- /dev/null
+++ b/testcases/kernel/fs/acl/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2026 IBM
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/fs/acl/acl_lib.h b/testcases/kernel/fs/acl/acl_lib.h
new file mode 100644
index 000000000..717c9ff1e
--- /dev/null
+++ b/testcases/kernel/fs/acl/acl_lib.h
@@ -0,0 +1,483 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2026 IBM
+ * Original shell test by Kai Zhao (ltcd3@cn.ibm.com)
+ * Converted to C by Sachin Sant <sachinp@linux.ibm.com>
+ *
+ * Common library for ACL and extended attribute tests using xattr API
+ */
+
+#ifndef ACL_LIB_H
+#define ACL_LIB_H
+
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdint.h>
+#include <endian.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/xattr.h>
+
+#include "config.h"
+#include "tst_test.h"
+#include "tst_safe_stdio.h"
+
+#define MNTPOINT	"mntpoint"
+#define TESTDIR		MNTPOINT "/testdir"
+#define TESTFILE	TESTDIR "/testfile"
+#define TESTSYMLINK	TESTDIR "/testsymlink"
+#define XATTR_BACKUP_FILE MNTPOINT "/xattr_backup.txt"
+
+/* Extended attribute test values */
+#define XATTR_TEST_DIR_NAME	"user.test_attr"
+#define XATTR_TEST_DIR_VALUE	"test_value"
+#define XATTR_TEST_DIR_SIZE	10
+#define XATTR_TEST_FILE_NAME	"user.file_attr"
+#define XATTR_TEST_FILE_VALUE	"file_val"
+#define XATTR_TEST_FILE_SIZE	8
+#define XATTR_TEST1_NAME	"user.test1"
+#define XATTR_TEST1_VALUE	"value1"
+#define XATTR_TEST1_SIZE	6
+#define XATTR_TEST2_NAME	"user.test2"
+#define XATTR_TEST2_VALUE	"value2"
+#define XATTR_TEST2_SIZE	6
+
+/*
+ * POSIX ACL xattr format definitions
+ * These match the kernel's internal representation
+ */
+#define POSIX_ACL_XATTR_VERSION	0x0002
+
+/* ACL entry tag types */
+#define ACL_UNDEFINED_TAG	0x00
+#define ACL_USER_OBJ		0x01
+#define ACL_USER		0x02
+#define ACL_GROUP_OBJ		0x04
+#define ACL_GROUP		0x08
+#define ACL_MASK		0x10
+#define ACL_OTHER		0x20
+
+/* ACL permissions */
+#define ACL_READ		0x04
+#define ACL_WRITE		0x02
+#define ACL_EXECUTE		0x01
+
+/* ACL xattr names */
+#define XATTR_NAME_POSIX_ACL_ACCESS	"system.posix_acl_access"
+#define XATTR_NAME_POSIX_ACL_DEFAULT	"system.posix_acl_default"
+
+/* ACL type for set/get operations */
+#define ACL_TYPE_ACCESS		1
+#define ACL_TYPE_DEFAULT	2
+
+/* Convert host to little-endian */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_le16(x) (x)
+#define cpu_to_le32(x) (x)
+#define le16_to_cpu(x) (x)
+#define le32_to_cpu(x) (x)
+#else
+#define cpu_to_le16(x) __builtin_bswap16(x)
+#define cpu_to_le32(x) __builtin_bswap32(x)
+#define le16_to_cpu(x) __builtin_bswap16(x)
+#define le32_to_cpu(x) __builtin_bswap32(x)
+#endif
+
+/*
+ * POSIX ACL xattr format as stored in kernel
+ * This is the on-disk/in-xattr representation
+ */
+struct posix_acl_xattr_header {
+	uint32_t a_version;
+};
+
+struct posix_acl_xattr_entry {
+	uint16_t e_tag;
+	uint16_t e_perm;
+	uint32_t e_id;
+};
+
+/*
+ * In-memory ACL representation for building ACLs
+ */
+#define MAX_ACL_ENTRIES 32
+
+struct acl_entry {
+	uint16_t tag;
+	uint16_t perm;
+	uint32_t id;
+};
+
+struct acl {
+	int count;
+	struct acl_entry entries[MAX_ACL_ENTRIES];
+};
+
+/* Helper functions */
+static inline void reset_test_path_no_chown(void)
+{
+	if (unlink(TESTSYMLINK) == -1 && errno != ENOENT)
+		tst_res(TWARN | TERRNO, "unlink(%s) failed", TESTSYMLINK);
+
+	if (unlink(TESTFILE) == -1 && errno != ENOENT)
+		tst_res(TWARN | TERRNO, "unlink(%s) failed", TESTFILE);
+
+	if (rmdir(TESTDIR) == -1 && errno != ENOENT)
+		tst_res(TWARN | TERRNO, "rmdir(%s) failed", TESTDIR);
+
+	SAFE_MKDIR(TESTDIR, 0755);
+}
+
+static inline void reset_test_path(void)
+{
+	reset_test_path_no_chown();
+}
+
+static inline void cleanup_testfile(void)
+{
+	if (unlink(TESTFILE) == -1 && errno != ENOENT)
+		tst_res(TWARN | TERRNO, "unlink(%s) failed", TESTFILE);
+}
+
+/*
+ * Initialize an empty ACL structure
+ */
+static inline struct acl *acl_init(void)
+{
+	struct acl *acl = malloc(sizeof(struct acl));
+
+	if (!acl)
+		return NULL;
+
+	acl->count = 0;
+	return acl;
+}
+
+/*
+ * Free an ACL structure
+ */
+static inline void acl_free(struct acl *acl)
+{
+	free(acl);
+}
+
+/*
+ * Add an ACL entry to the ACL structure
+ */
+static inline int acl_add_entry(struct acl *acl, uint16_t tag, uint16_t perm,
+				uint32_t id)
+{
+	if (acl->count >= MAX_ACL_ENTRIES) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	acl->entries[acl->count].tag = tag;
+	acl->entries[acl->count].perm = perm;
+	acl->entries[acl->count].id = id;
+	acl->count++;
+
+	return 0;
+}
+
+/*
+ * Set ACL on a file using xattr.
+ *
+ * The kernel stores access ACLs only when they differ from the file mode.
+ * If the ACL is equivalent to st_mode, the xattr is removed and future
+ * getxattr() calls return ENODATA. Mirror libacl semantics by treating
+ * ENODATA as a valid minimal ACL derived from st_mode.
+ */
+static inline int acl_set_file(const char *path, int type, struct acl *acl)
+{
+	const char *xattr_name;
+	size_t size;
+	char *buf;
+	struct posix_acl_xattr_header *header;
+	struct posix_acl_xattr_entry *entries;
+	int i, ret;
+
+	if (type == ACL_TYPE_ACCESS)
+		xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
+	else if (type == ACL_TYPE_DEFAULT)
+		xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
+	else {
+		errno = EINVAL;
+		return -1;
+	}
+
+	size = sizeof(struct posix_acl_xattr_header) +
+	       acl->count * sizeof(struct posix_acl_xattr_entry);
+
+	buf = malloc(size);
+	if (!buf)
+		return -1;
+
+	header = (struct posix_acl_xattr_header *)buf;
+	header->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
+
+	entries = (struct posix_acl_xattr_entry *)(buf + sizeof(*header));
+
+	for (i = 0; i < acl->count; i++) {
+		entries[i].e_tag = cpu_to_le16(acl->entries[i].tag);
+		entries[i].e_perm = cpu_to_le16(acl->entries[i].perm);
+		entries[i].e_id = cpu_to_le32(acl->entries[i].id);
+	}
+
+	ret = setxattr(path, xattr_name, buf, size, 0);
+	free(buf);
+
+	return ret;
+}
+
+static inline int acl_add_mode_entries(struct acl *acl, mode_t mode)
+{
+	if (acl_add_entry(acl, ACL_USER_OBJ, (mode >> 6) & 07, 0) < 0)
+		return -1;
+
+	if (acl_add_entry(acl, ACL_GROUP_OBJ, (mode >> 3) & 07, 0) < 0)
+		return -1;
+
+	if (acl_add_entry(acl, ACL_OTHER, mode & 07, 0) < 0)
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Synthesize an ACL from file mode bits.
+ * Used when no xattr exists for an access ACL.
+ */
+static inline struct acl *acl_from_mode(const char *path)
+{
+	struct acl *acl;
+	struct stat st;
+
+	if (stat(path, &st) < 0)
+		return NULL;
+
+	acl = acl_init();
+	if (!acl)
+		return NULL;
+
+	if (acl_add_mode_entries(acl, st.st_mode) < 0) {
+		acl_free(acl);
+		return NULL;
+	}
+
+	return acl;
+}
+
+/*
+ * Get ACL from a file using xattr.
+ *
+ * Access ACLs equivalent to file mode may not have a backing xattr at all.
+ * In that case synthesize the base ACL from st_mode so callers observe the
+ * same behavior as acl_get_file(3).
+ */
+static inline struct acl *acl_get_file(const char *path, int type)
+{
+	const char *xattr_name;
+	ssize_t size;
+	char *buf;
+	struct posix_acl_xattr_header *header;
+	struct posix_acl_xattr_entry *entries;
+	struct acl *acl;
+	int i, count;
+
+	if (type == ACL_TYPE_ACCESS)
+		xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
+	else if (type == ACL_TYPE_DEFAULT)
+		xattr_name = XATTR_NAME_POSIX_ACL_DEFAULT;
+	else {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	size = getxattr(path, xattr_name, NULL, 0);
+	if (size < 0) {
+		if (errno != ENODATA || type != ACL_TYPE_ACCESS)
+			return NULL;
+
+		return acl_from_mode(path);
+	}
+
+	/* Handle race: xattr removed between size check and actual read */
+	if (size == 0)
+		return acl_from_mode(path);
+
+	buf = malloc(size);
+	if (!buf)
+		return NULL;
+
+	size = getxattr(path, xattr_name, buf, size);
+	if (size < 0) {
+		free(buf);
+		/* Handle race: xattr removed between size check and read */
+		if (errno == ENODATA && type == ACL_TYPE_ACCESS)
+			return acl_from_mode(path);
+		return NULL;
+	}
+
+	header = (struct posix_acl_xattr_header *)buf;
+	if (le32_to_cpu(header->a_version) != POSIX_ACL_XATTR_VERSION) {
+		free(buf);
+		errno = EINVAL;
+		return NULL;
+	}
+
+	count = (size - sizeof(*header)) / sizeof(struct posix_acl_xattr_entry);
+	entries = (struct posix_acl_xattr_entry *)(buf + sizeof(*header));
+
+	acl = acl_init();
+	if (!acl) {
+		free(buf);
+		return NULL;
+	}
+
+	for (i = 0; i < count; i++) {
+		uint16_t tag = le16_to_cpu(entries[i].e_tag);
+		uint16_t perm = le16_to_cpu(entries[i].e_perm);
+		uint32_t id = le32_to_cpu(entries[i].e_id);
+
+		if (acl_add_entry(acl, tag, perm, id) < 0) {
+			acl_free(acl);
+			free(buf);
+			return NULL;
+		}
+	}
+
+	free(buf);
+	return acl;
+}
+
+/*
+ * Check if an ACL entry has a specific permission
+ */
+static inline int acl_entry_has_perm(struct acl_entry *entry, uint16_t perm)
+{
+	return (entry->perm & perm) == perm;
+}
+
+/*
+ * Check if an ACL entry has all rwx permissions
+ */
+static inline int acl_entry_has_rwx(struct acl_entry *entry)
+{
+	return acl_entry_has_perm(entry, ACL_READ) &&
+	       acl_entry_has_perm(entry, ACL_WRITE) &&
+	       acl_entry_has_perm(entry, ACL_EXECUTE);
+}
+
+/*
+ * Find an ACL entry by tag type
+ */
+static inline struct acl_entry *acl_find_entry(struct acl *acl, uint16_t tag,
+					       uint32_t id)
+{
+	int i;
+
+	for (i = 0; i < acl->count; i++) {
+		if (acl->entries[i].tag == tag) {
+			if (tag == ACL_USER || tag == ACL_GROUP) {
+				if (acl->entries[i].id == id)
+					return &acl->entries[i];
+			} else {
+				return &acl->entries[i];
+			}
+		}
+	}
+
+	return NULL;
+}
+
+/*
+ * Update ACL mask permissions
+ */
+static inline int acl_set_mask_perms(struct acl *acl, uint16_t perm)
+{
+	struct acl_entry *mask_entry = acl_find_entry(acl, ACL_MASK, 0);
+
+	if (!mask_entry) {
+		errno = ENOENT;
+		return -1;
+	}
+
+	mask_entry->perm = perm;
+	return 0;
+}
+
+static inline int create_file_as(uid_t uid, gid_t gid, mode_t mode,
+				 int use_umask, mode_t mask)
+{
+	pid_t pid;
+	int status;
+
+	pid = SAFE_FORK();
+	if (!pid) {
+		int fd, err;
+
+		if (setgroups(0, NULL) == -1) {
+			err = errno;
+			_exit(err);
+		}
+
+		if (setgid(gid) == -1) {
+			err = errno;
+			_exit(err);
+		}
+
+		if (setuid(uid) == -1) {
+			err = errno;
+			_exit(err);
+		}
+
+		if (use_umask)
+			umask(mask);
+
+		fd = open(TESTFILE, O_CREAT | O_WRONLY, mode);
+		if (fd >= 0) {
+			close(fd);
+			_exit(0);
+		}
+
+		err = errno;
+		_exit(err);
+	}
+
+	SAFE_WAITPID(pid, &status, 0);
+
+	if (!WIFEXITED(status))
+		tst_brk(TBROK, "Child terminated abnormally");
+
+	return WEXITSTATUS(status);
+}
+
+static inline int try_create_as(uid_t uid, gid_t gid, mode_t mode)
+{
+	return create_file_as(uid, gid, mode, 0, 0);
+}
+
+static inline int create_with_umask_as(uid_t uid, gid_t gid, mode_t mode,
+					mode_t mask)
+{
+	return create_file_as(uid, gid, mode, 1, mask);
+}
+
+static inline void cleanup_test_paths(void)
+{
+	if (unlink(TESTSYMLINK) == -1 && errno != ENOENT)
+		tst_res(TWARN | TERRNO, "unlink(%s) failed", TESTSYMLINK);
+
+	if (unlink(TESTFILE) == -1 && errno != ENOENT)
+		tst_res(TWARN | TERRNO, "unlink(%s) failed", TESTFILE);
+
+	if (rmdir(TESTDIR) == -1 && errno != ENOENT)
+		tst_res(TWARN | TERRNO, "rmdir(%s) failed", TESTDIR);
+}
+
+#endif /* ACL_LIB_H */
diff --git a/testcases/kernel/fs/acl/acl_user_obj01.c b/testcases/kernel/fs/acl/acl_user_obj01.c
new file mode 100644
index 000000000..01abfbf4e
--- /dev/null
+++ b/testcases/kernel/fs/acl/acl_user_obj01.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 IBM
+ *
+ * Original shell test by Kai Zhao (ltcd3@cn.ibm.com)
+ * Converted to C by Sachin Sant <sachinp@linux.ibm.com>
+ */
+
+/*\
+ * Test ACL_USER_OBJ permissions using direct xattr manipulation.
+ *
+ * Verify that owner permissions (ACL_USER_OBJ) correctly control access
+ * to files and directories. The test validates that:
+ * - ACL_USER_OBJ permissions are applied directly as the owner bits
+ * - Setting ACL_USER_OBJ=rwx via setxattr() overrides a previous
+ *   chmod restriction
+ * - Owner permissions work independently of group and other permissions
+ *
+ * This test uses arbitrary UIDs without creating actual users, testing
+ * only the kernel ACL implementation.
+ */
+
+#include "acl_lib.h"
+
+#define TEST_UID 1000
+#define TEST_GID 1000
+
+/*
+ * Test permission bits deny access.
+ * Owner should be denied write access when mode is 0500.
+ */
+static void test_deny_by_mode(void)
+{
+	int err;
+
+	tst_res(TINFO, "Testing permission bits deny access");
+	reset_test_path();
+
+	SAFE_CHOWN(TESTDIR, TEST_UID, TEST_GID);
+	SAFE_CHMOD(TESTDIR, 0500);
+
+	err = try_create_as(TEST_UID, TEST_GID, 0644);
+	if (!err) {
+		cleanup_testfile();
+		tst_res(TFAIL, "Created file without write permission");
+		return;
+	}
+
+	if (err != EACCES) {
+		errno = err;
+		tst_res(TFAIL | TERRNO, "Expected EACCES from owner create");
+		return;
+	}
+
+	tst_res(TPASS, "File creation denied by permission bits");
+}
+
+/*
+ * Test ACL_USER_OBJ grants access.
+ * Setting ACL_USER_OBJ=rwx should override previous chmod restriction.
+ */
+static void test_grant_by_acl(void)
+{
+	struct acl *acl = NULL;
+	int err;
+
+	tst_res(TINFO, "Testing ACL_USER_OBJ grants access");
+	reset_test_path();
+
+	SAFE_CHOWN(TESTDIR, TEST_UID, TEST_GID);
+	SAFE_CHMOD(TESTDIR, 0500);
+
+	acl = acl_init();
+	if (!acl)
+		tst_brk(TBROK | TERRNO, "acl_init failed");
+
+	if (acl_add_entry(acl, ACL_USER_OBJ,
+			  ACL_READ | ACL_WRITE | ACL_EXECUTE, 0) < 0)
+		goto cleanup_acl;
+
+	if (acl_add_entry(acl, ACL_GROUP_OBJ, 0, 0) < 0)
+		goto cleanup_acl;
+
+	if (acl_add_entry(acl, ACL_OTHER, 0, 0) < 0)
+		goto cleanup_acl;
+
+	if (acl_set_file(TESTDIR, ACL_TYPE_ACCESS, acl) < 0) {
+		if (errno == EOPNOTSUPP) {
+			acl_free(acl);
+			tst_brk(TCONF | TERRNO, "ACL not supported");
+		}
+		goto cleanup_acl;
+	}
+
+	acl_free(acl);
+	acl = NULL;
+
+	err = try_create_as(TEST_UID, TEST_GID, 0644);
+	if (err) {
+		errno = err;
+		tst_res(TFAIL | TERRNO,
+			"Failed to create file with ACL_USER_OBJ rwx");
+		return;
+	}
+
+	cleanup_testfile();
+	tst_res(TPASS, "ACL_USER_OBJ permissions work correctly");
+	return;
+
+cleanup_acl:
+	acl_free(acl);
+	tst_brk(TBROK | TERRNO, "ACL setup failed");
+}
+
+static void run(unsigned int n)
+{
+	switch (n) {
+	case 0:
+		test_deny_by_mode();
+		break;
+	case 1:
+		test_grant_by_acl();
+		break;
+	}
+}
+
+static void setup(void)
+{
+	reset_test_path();
+}
+
+static void cleanup(void)
+{
+	cleanup_test_paths();
+}
+
+static struct tst_test test = {
+	.test = run,
+	.tcnt = 2,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+	.mount_device = 1,
+	.mntpoint = MNTPOINT,
+	.forks_child = 1,
+	.filesystems = (struct tst_fs[]) {
+		{.type = "ext2", .mnt_data = "acl"},
+		{.type = "ext3", .mnt_data = "acl"},
+		{.type = "ext4", .mnt_data = "acl"},
+		{.type = "xfs"},
+		{.type = "btrfs"},
+		{}
+	}
+};
-- 
2.39.1



More information about the ltp mailing list