FSTests Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v12 0/6] fstests: add idmapped mounts tests
@ 2021-03-28 22:33 Christian Brauner
  2021-03-28 22:33 ` [PATCH v12 1/6] generic/631: add test for detached mount propagation Christian Brauner
                   ` (6 more replies)
  0 siblings, 7 replies; 24+ messages in thread
From: Christian Brauner @ 2021-03-28 22:33 UTC (permalink / raw)
  To: Eryu Guan, fstests, Christoph Hellwig
  Cc: Darrick J . Wong, David Howells, Christian Brauner

From: Christian Brauner <christian.brauner@ubuntu.com>

Hey everyone,

This series is available from:
https://git.kernel.org/brauner/xfstests-dev/h/idmapped_mounts
https://gitlab.com/brauner/xfstests/-/tree/idmapped_mounts
https://github.com/brauner/xfstests/tree/idmapped_mounts

/* v12 */
- Main change is a fix to the io_uring tests. io_uring_wait_cqe()
  doesn't set errno, it returns a negative errno.
- Make sure we also run without error when libcap isn't available (That
  was always the goal but the logic missed a few new tests.)

/* v11 */
Reworked according to Amir's comments.

/* v10 */
Reworked according to Eryu's comments.

/* v9 */
Rebased onto current master.

ubuntu@f1-vm:~/src/git/xfstests$ sudo ./check -g idmapped
FSTYP         -- xfs (debug)
PLATFORM      -- Linux/x86_64 f1-vm 5.12.0-rc3-syz #18 SMP PREEMPT Fri Mar 26 13:27:16 UTC 2021
MKFS_OPTIONS  -- -f -bsize=4096 /dev/loop1
MOUNT_OPTIONS -- /dev/loop1 /mnt/scratch

generic/632 files ...  27s
xfs/529 files ...  67s
xfs/530 files ...  43s
Ran: generic/632 xfs/529 xfs/530
Passed all 3 tests

Thanks!
Christian

Christian Brauner (6):
  generic/631: add test for detached mount propagation
  generic/632: add fstests for idmapped mounts
  common/rc: add _scratch_{u}mount_idmapped() helpers
  common/quota: move _qsetup() helper to common code
  xfs/529: quotas and idmapped mounts
  xfs/530: quotas on idmapped mounts

 .gitignore                            |    3 +
 README                                |    5 +-
 common/quota                          |   20 +
 common/rc                             |   60 +
 configure.ac                          |    2 +
 include/builddefs.in                  |    1 +
 m4/Makefile                           |    1 +
 m4/package_libcap.m4                  |    4 +
 src/Makefile                          |    8 +-
 src/detached_mounts_propagation.c     |  189 +
 src/feature.c                         |   40 +-
 src/idmapped-mounts/Makefile          |   40 +
 src/idmapped-mounts/idmapped-mounts.c | 8873 +++++++++++++++++++++++++
 src/idmapped-mounts/missing.h         |  151 +
 src/idmapped-mounts/mount-idmapped.c  |  431 ++
 src/idmapped-mounts/utils.c           |  134 +
 src/idmapped-mounts/utils.h           |   30 +
 tests/generic/631                     |   43 +
 tests/generic/631.out                 |    2 +
 tests/generic/632                     |   42 +
 tests/generic/632.out                 |    2 +
 tests/generic/group                   |    2 +
 tests/xfs/050                         |   19 -
 tests/xfs/299                         |   19 -
 tests/xfs/529                         |  377 ++
 tests/xfs/529.out                     |  657 ++
 tests/xfs/530                         |  212 +
 tests/xfs/530.out                     |  129 +
 tests/xfs/group                       |    2 +
 29 files changed, 11453 insertions(+), 45 deletions(-)
 create mode 100644 m4/package_libcap.m4
 create mode 100644 src/detached_mounts_propagation.c
 create mode 100644 src/idmapped-mounts/Makefile
 create mode 100644 src/idmapped-mounts/idmapped-mounts.c
 create mode 100644 src/idmapped-mounts/missing.h
 create mode 100644 src/idmapped-mounts/mount-idmapped.c
 create mode 100644 src/idmapped-mounts/utils.c
 create mode 100644 src/idmapped-mounts/utils.h
 create mode 100644 tests/generic/631
 create mode 100644 tests/generic/631.out
 create mode 100644 tests/generic/632
 create mode 100644 tests/generic/632.out
 create mode 100644 tests/xfs/529
 create mode 100644 tests/xfs/529.out
 create mode 100644 tests/xfs/530
 create mode 100644 tests/xfs/530.out


base-commit: f6ddaf130d5b0817278afe441fdde52f464f321b
-- 
2.27.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v12 1/6] generic/631: add test for detached mount propagation
  2021-03-28 22:33 [PATCH v12 0/6] fstests: add idmapped mounts tests Christian Brauner
@ 2021-03-28 22:33 ` Christian Brauner
  2021-03-28 22:33 ` [PATCH v12 3/6] common/rc: add _scratch_{u}mount_idmapped() helpers Christian Brauner
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 24+ messages in thread
From: Christian Brauner @ 2021-03-28 22:33 UTC (permalink / raw)
  To: Eryu Guan, fstests, Christoph Hellwig
  Cc: Darrick J . Wong, David Howells, Christian Brauner

From: Christian Brauner <christian.brauner@ubuntu.com>

Regression test to verify that creating a series of detached mounts,
attaching them to the filesystem, and unmounting them does not trigger an
integer overflow in ns->mounts causing the kernel to block any new mounts in
count_mounts() and returning ENOSPC because it falsely assumes that the
maximum number of mounts in the mount namespace has been reached, i.e. it
thinks it can't fit the new mounts into the mount namespace anymore.

The test is written in a way that it will leave the host's mount
namespace intact so we are sure to never make the host's mount namespace
unuseable!

Link: https://git.kernel.org/torvalds/c/ee2e3f50629f17b0752b55b2566c15ce8dafb557
Cc: Eryu Guan <guan@eryu.me>
Cc: David Howells <dhowells@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
/* v1 - v8 */
patch not present

/* v9 */
- Christian Brauner <christian.brauner@ubuntu.com>:
  - Rebased on current master.

/* v10 */
- Eryu Guan <guan@eryu.me>:
  - Add missing checks whether test is supported.
  - Move status=$? assignment up.

/* v11 */
unchanged

/* v12 */
unchanged
---
 .gitignore                        |   1 +
 src/Makefile                      |   3 +-
 src/detached_mounts_propagation.c | 252 ++++++++++++++++++++++++++++++
 tests/generic/631                 |  43 +++++
 tests/generic/631.out             |   2 +
 tests/generic/group               |   1 +
 6 files changed, 301 insertions(+), 1 deletion(-)
 create mode 100644 src/detached_mounts_propagation.c
 create mode 100644 tests/generic/631
 create mode 100644 tests/generic/631.out

diff --git a/.gitignore b/.gitignore
index f3bc0a4f..72bd40a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -62,6 +62,7 @@
 /src/cloner
 /src/dbtest
 /src/deduperace
+/src/detached_mounts_propagation
 /src/devzero
 /src/dio-interleaved
 /src/dio-invalidate-cache
diff --git a/src/Makefile b/src/Makefile
index 3d729a34..99019e6e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -29,7 +29,8 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \
 	attr-list-by-handle-cursor-test listxattr dio-interleaved t_dir_type \
 	dio-invalidate-cache stat_test t_encrypted_d_revalidate \
 	attr_replace_test swapon mkswap t_attr_corruption t_open_tmpfiles \
-	fscrypt-crypt-util bulkstat_null_ocount splice-test chprojid_fail
+	fscrypt-crypt-util bulkstat_null_ocount splice-test chprojid_fail \
+	detached_mounts_propagation
 
 SUBDIRS = log-writes perf
 
diff --git a/src/detached_mounts_propagation.c b/src/detached_mounts_propagation.c
new file mode 100644
index 00000000..4a588e46
--- /dev/null
+++ b/src/detached_mounts_propagation.c
@@ -0,0 +1,252 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/*
+ * Copyright (c) 2021 Christian Brauner <christian.brauner@ubuntu.com>
+ * All Rights Reserved.
+ *
+ * Regression test to verify that creating a series of detached mounts,
+ * attaching them to the filesystem, and unmounting them does not trigger an
+ * integer overflow in ns->mounts causing the kernel to block any new mounts in
+ * count_mounts() and returning ENOSPC because it falsely assumes that the
+ * maximum number of mounts in the mount namespace has been reached, i.e. it
+ * thinks it can't fit the new mounts into the mount namespace anymore.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <limits.h>
+#include <sched.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* open_tree() */
+#ifndef OPEN_TREE_CLONE
+#define OPEN_TREE_CLONE 1
+#endif
+
+#ifndef OPEN_TREE_CLOEXEC
+#define OPEN_TREE_CLOEXEC O_CLOEXEC
+#endif
+
+#ifndef __NR_open_tree
+	#if defined __alpha__
+		#define __NR_open_tree 538
+	#elif defined _MIPS_SIM
+		#if _MIPS_SIM == _MIPS_SIM_ABI32	/* o32 */
+			#define __NR_open_tree 4428
+		#endif
+		#if _MIPS_SIM == _MIPS_SIM_NABI32	/* n32 */
+			#define __NR_open_tree 6428
+		#endif
+		#if _MIPS_SIM == _MIPS_SIM_ABI64	/* n64 */
+			#define __NR_open_tree 5428
+		#endif
+	#elif defined __ia64__
+		#define __NR_open_tree (428 + 1024)
+	#else
+		#define __NR_open_tree 428
+	#endif
+#endif
+
+/* move_mount() */
+#ifndef MOVE_MOUNT_F_EMPTY_PATH
+#define MOVE_MOUNT_F_EMPTY_PATH 0x00000004 /* Empty from path permitted */
+#endif
+
+#ifndef __NR_move_mount
+	#if defined __alpha__
+		#define __NR_move_mount 539
+	#elif defined _MIPS_SIM
+		#if _MIPS_SIM == _MIPS_SIM_ABI32	/* o32 */
+			#define __NR_move_mount 4429
+		#endif
+		#if _MIPS_SIM == _MIPS_SIM_NABI32	/* n32 */
+			#define __NR_move_mount 6429
+		#endif
+		#if _MIPS_SIM == _MIPS_SIM_ABI64	/* n64 */
+			#define __NR_move_mount 5429
+		#endif
+	#elif defined __ia64__
+		#define __NR_move_mount (428 + 1024)
+	#else
+		#define __NR_move_mount 429
+	#endif
+#endif
+
+static inline int sys_open_tree(int dfd, const char *filename, unsigned int flags)
+{
+	return syscall(__NR_open_tree, dfd, filename, flags);
+}
+
+static inline int sys_move_mount(int from_dfd, const char *from_pathname, int to_dfd,
+				 const char *to_pathname, unsigned int flags)
+{
+	return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, to_pathname, flags);
+}
+
+static bool is_shared_mountpoint(const char *path)
+{
+	bool shared = false;
+	FILE *f = NULL;
+	char *line = NULL;
+	int i;
+	size_t len = 0;
+
+	f = fopen("/proc/self/mountinfo", "re");
+	if (!f)
+		return 0;
+
+	while (getline(&line, &len, f) > 0) {
+		char *slider1, *slider2;
+
+		for (slider1 = line, i = 0; slider1 && i < 4; i++)
+			slider1 = strchr(slider1 + 1, ' ');
+
+		if (!slider1)
+			continue;
+
+		slider2 = strchr(slider1 + 1, ' ');
+		if (!slider2)
+			continue;
+
+		*slider2 = '\0';
+		if (strcmp(slider1 + 1, path) == 0) {
+			/* This is the path. Is it shared? */
+			slider1 = strchr(slider2 + 1, ' ');
+			if (slider1 && strstr(slider1, "shared:")) {
+				shared = true;
+				break;
+			}
+		}
+	}
+	fclose(f);
+	free(line);
+
+	return shared;
+}
+
+static void usage(void)
+{
+	const char *text = "mount-new [--recursive] <base-dir>\n";
+	fprintf(stderr, "%s", text);
+	_exit(EXIT_SUCCESS);
+}
+
+#define exit_usage(format, ...)                              \
+	({                                                   \
+		fprintf(stderr, format "\n", ##__VA_ARGS__); \
+		usage();                                     \
+	})
+
+#define exit_log(format, ...)                                \
+	({                                                   \
+		fprintf(stderr, format "\n", ##__VA_ARGS__); \
+		exit(EXIT_FAILURE);                          \
+	})
+
+static const struct option longopts[] = {
+	{"help",	no_argument,		0,	'a'},
+	{ NULL,		no_argument,		0,	 0 },
+};
+
+int main(int argc, char *argv[])
+{
+	int exit_code = EXIT_SUCCESS, index = 0;
+	int dfd, fd_tree, new_argc, ret;
+	char *base_dir;
+	char *const *new_argv;
+	char target[PATH_MAX];
+
+	while ((ret = getopt_long_only(argc, argv, "", longopts, &index)) != -1) {
+		switch (ret) {
+		case 'a':
+			/* fallthrough */
+		default:
+			usage();
+		}
+	}
+
+	new_argv = &argv[optind];
+	new_argc = argc - optind;
+	if (new_argc < 1)
+		exit_usage("Missing base directory\n");
+	base_dir = new_argv[0];
+
+	if (*base_dir != '/')
+		exit_log("Please specify an absolute path");
+
+	/* Ensure that target is a shared mountpoint. */
+	if (!is_shared_mountpoint(base_dir))
+		exit_log("Please ensure that \"%s\" is a shared mountpoint", base_dir);
+
+	ret = unshare(CLONE_NEWNS);
+	if (ret < 0)
+		exit_log("%m - Failed to create new mount namespace");
+
+	ret = mount(NULL, base_dir, NULL, MS_REC | MS_SHARED, NULL);
+	if (ret < 0)
+		exit_log("%m - Failed to make base_dir shared mountpoint");
+
+	dfd = open(base_dir, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
+	if (dfd < 0)
+		exit_log("%m - Failed to open base directory \"%s\"", base_dir);
+
+	ret = mkdirat(dfd, "detached-move-mount", 0755);
+	if (ret < 0)
+		exit_log("%m - Failed to create required temporary directories");
+
+	ret = snprintf(target, sizeof(target), "%s/detached-move-mount", base_dir);
+	if (ret < 0 || (size_t)ret >= sizeof(target))
+		exit_log("%m - Failed to assemble target path");
+
+	/*
+	 * Having a mount table with 10000 mounts is already quite excessive
+	 * and shoult account even for weird test systems.
+	 */
+	for (size_t i = 0; i < 10000; i++) {
+		fd_tree = sys_open_tree(dfd, "detached-move-mount",
+					OPEN_TREE_CLONE |
+					OPEN_TREE_CLOEXEC |
+					AT_EMPTY_PATH);
+		if (fd_tree < 0) {
+			if (errno == ENOSYS) /* New mount API not (fully) supported. */
+				break;
+
+			fprintf(stderr, "%m - Failed to open %d(detached-move-mount)", dfd);
+			exit_code = EXIT_FAILURE;
+			break;
+		}
+
+		ret = sys_move_mount(fd_tree, "", dfd, "detached-move-mount", MOVE_MOUNT_F_EMPTY_PATH);
+		if (ret < 0) {
+			if (errno == ENOSPC)
+				fprintf(stderr, "%m - Buggy mount counting");
+			else if (errno == ENOSYS) /* New mount API not (fully) supported. */
+				break;
+			else
+				fprintf(stderr, "%m - Failed to attach mount to %d(detached-move-mount)", dfd);
+			exit_code = EXIT_FAILURE;
+			break;
+		}
+		close(fd_tree);
+
+		ret = umount2(target, MNT_DETACH);
+		if (ret < 0) {
+			fprintf(stderr, "%m - Failed to unmount %s", target);
+			exit_code = EXIT_FAILURE;
+			break;
+		}
+	}
+
+	(void)unlinkat(dfd, "detached-move-mount", AT_REMOVEDIR);
+	close(dfd);
+
+	exit(exit_code);
+}
diff --git a/tests/generic/631 b/tests/generic/631
new file mode 100644
index 00000000..0b6cac42
--- /dev/null
+++ b/tests/generic/631
@@ -0,0 +1,43 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2021 Christian Brauner <christian.brauner@ubuntu.com>
+# All Rights Reserved.
+#
+# FS QA Test No. 631
+#
+# Regression test to verify that creating a series of detached mounts,
+# attaching them to the filesystem, and unmounting them does not trigger an
+# integer overflow in ns->mounts causing the kernel to block any new mounts in
+# count_mounts() and returning ENOSPC because it falsely assumes that the
+# maximum number of mounts in the mount namespace has been reached, i.e. it
+# thinks it can't fit the new mounts into the mount namespace anymore.
+#
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+	cd /
+	rm -f $tmp.*
+}
+
+. ./common/rc
+
+rm -f $seqres.full
+
+_supported_fs generic
+_require_test
+_require_test_program "detached_mounts_propagation"
+
+$here/src/detached_mounts_propagation $TEST_DIR >> $seqres.full
+status=$?
+
+echo silence is golden
+exit
diff --git a/tests/generic/631.out b/tests/generic/631.out
new file mode 100644
index 00000000..ce88f447
--- /dev/null
+++ b/tests/generic/631.out
@@ -0,0 +1,2 @@
+QA output created by 631
+silence is golden
diff --git a/tests/generic/group b/tests/generic/group
index 7c7531d1..151f8af2 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -633,3 +633,4 @@
 628 auto quick rw clone
 629 auto quick rw copy_range
 630 auto quick rw dedupe clone
+631 auto quick mount
-- 
2.27.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v12 3/6] common/rc: add _scratch_{u}mount_idmapped() helpers
  2021-03-28 22:33 [PATCH v12 0/6] fstests: add idmapped mounts tests Christian Brauner
  2021-03-28 22:33 ` [PATCH v12 1/6] generic/631: add test for detached mount propagation Christian Brauner
@ 2021-03-28 22:33 ` Christian Brauner
  2021-03-28 22:33 ` [PATCH v12 4/6] common/quota: move _qsetup() helper to common code Christian Brauner
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 24+ messages in thread
From: Christian Brauner @ 2021-03-28 22:33 UTC (permalink / raw)
  To: Eryu Guan, fstests, Christoph Hellwig
  Cc: Darrick J . Wong, David Howells, Christian Brauner

From: Christian Brauner <christian.brauner@ubuntu.com>

They will be used in follow-up patches for xfs quota tests but might be
useful for other tests in the future.

Cc: Eryu Guan <guan@eryu.me>
Cc: Christoph Hellwig <hch@lst.de>
Cc: David Howells <dhowells@redhat.com>
Cc: fstests@vger.kernel.org
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
/* v1 - v9 */
patch not present

/* v10 */
patch introduced

/* v11 */
- Amir Goldstein <amir73il@gmail.com>:
  - Minor Makefile style nit.
  - Add missing "/" when calculating maxium path length.
  - Handle the case where user gives us a path to userns.

/* v12 */
- Eryu Guan <guan@eryu.me>:
  - Fix helper installation.
---
 .gitignore                           |   1 +
 common/rc                            |  35 +++
 src/idmapped-mounts/Makefile         |  13 +-
 src/idmapped-mounts/mount-idmapped.c | 431 +++++++++++++++++++++++++++
 src/idmapped-mounts/utils.c          |   2 +-
 src/idmapped-mounts/utils.h          |   1 +
 6 files changed, 478 insertions(+), 5 deletions(-)
 create mode 100644 src/idmapped-mounts/mount-idmapped.c

diff --git a/.gitignore b/.gitignore
index 3229bb26..4cc9c807 100644
--- a/.gitignore
+++ b/.gitignore
@@ -179,6 +179,7 @@
 /src/aio-dio-regress/aiocp
 /src/aio-dio-regress/aiodio_sparse2
 /src/idmapped-mounts/idmapped-mounts
+/src/idmapped-mounts/mount-idmapped
 /src/log-writes/replay-log
 /src/perf/*.pyc
 
diff --git a/common/rc b/common/rc
index a8b375a2..351996fc 100644
--- a/common/rc
+++ b/common/rc
@@ -342,6 +342,36 @@ _scratch_mount()
 	_try_scratch_mount $* || _fail "mount failed"
 }
 
+_scratch_mount_idmapped()
+{
+	local type="$1"
+	local id="$2"
+
+	if [ "$type" = "u" ]; then
+		# This means root will be able to create files as uid %id in
+		# the underlying filesystem by going through the idmapped mount.
+		$here/src/idmapped-mounts/mount-idmapped --map-mount u:0:$id:1 \
+							 --map-mount u:$id:0:1 \
+							 --map-mount g:0:0:1 \
+							 "$SCRATCH_MNT" "$SCRATCH_MNT" || _fail "mount-idmapped failed"
+	elif [ "$type" = "g" ]; then
+		# This means root will be able to create files as gid %id in
+		# the underlying filesystem by going through the idmapped mount.
+		$here/src/idmapped-mounts/mount-idmapped --map-mount g:0:$id:1 \
+							 --map-mount g:$id:0:1 \
+							 --map-mount u:0:0:1 \
+							 "$SCRATCH_MNT" "$SCRATCH_MNT" || _fail "mount-idmapped failed"
+	elif [ "$type" = "b" ]; then
+		# This means root will be able to create files as uid and gid
+		# %id in the underlying filesystem by going through the idmapped mount.
+		$here/src/idmapped-mounts/mount-idmapped --map-mount b:0:$id:1 \
+							 --map-mount b:$id:0:1 \
+							 "$SCRATCH_MNT" "$SCRATCH_MNT" || _fail "mount-idmapped failed"
+	else
+		_fail "usage: either \"u\" (uid), \"g\" (gid), or \"b\" (uid and gid) must be specified "
+	fi
+}
+
 _scratch_unmount()
 {
 	case "$FSTYP" in
@@ -357,6 +387,11 @@ _scratch_unmount()
 	esac
 }
 
+_scratch_umount_idmapped()
+{
+	$UMOUNT_PROG $SCRATCH_MNT
+}
+
 _scratch_remount()
 {
     local opts="$1"
diff --git a/src/idmapped-mounts/Makefile b/src/idmapped-mounts/Makefile
index 6a934146..ad4ddc99 100644
--- a/src/idmapped-mounts/Makefile
+++ b/src/idmapped-mounts/Makefile
@@ -3,9 +3,10 @@
 TOPDIR = ../..
 include $(TOPDIR)/include/builddefs
 
-TARGETS = idmapped-mounts
+TARGETS = idmapped-mounts mount-idmapped
+CFILES_IDMAPPED_MOUNTS = idmapped-mounts.c utils.c
+CFILES_MOUNT_IDMAPPED = mount-idmapped.c utils.c
 
-CFILES = idmapped-mounts.c utils.c
 HFILES = missing.h utils.h
 LLDLIBS += -pthread
 LDIRT = $(TARGETS)
@@ -24,9 +25,13 @@ depend: .dep
 
 include $(BUILDRULES)
 
-$(TARGETS): $(CFILES)
+idmapped-mounts: $(CFILES_IDMAPPED_MOUNTS)
 	@echo "    [CC]    $@"
-	$(Q)$(LTLINK) $(CFILES) -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
+	$(Q)$(LTLINK) $(CFILES_IDMAPPED_MOUNTS) -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
+
+mount-idmapped: $(CFILES_MOUNT_IDMAPPED)
+	@echo "    [CC]    $@"
+	$(Q)$(LTLINK) $(CFILES_MOUNT_IDMAPPED) -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS)
 
 install:
 	$(INSTALL) -m 755 -d $(PKG_LIB_DIR)/src/idmapped-mounts
diff --git a/src/idmapped-mounts/mount-idmapped.c b/src/idmapped-mounts/mount-idmapped.c
new file mode 100644
index 00000000..5f5ba5d2
--- /dev/null
+++ b/src/idmapped-mounts/mount-idmapped.c
@@ -0,0 +1,431 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "../global.h"
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <limits.h>
+#include <linux/bpf.h>
+#include <linux/sched.h>
+#include <linux/seccomp.h>
+#include <sched.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "missing.h"
+#include "utils.h"
+
+/* A few helpful macros. */
+#define STRLITERALLEN(x) (sizeof(""x"") - 1)
+
+#define INTTYPE_TO_STRLEN(type)             \
+	(2 + (sizeof(type) <= 1             \
+		  ? 3                       \
+		  : sizeof(type) <= 2       \
+			? 5                 \
+			: sizeof(type) <= 4 \
+			      ? 10          \
+			      : sizeof(type) <= 8 ? 20 : sizeof(int[-2 * (sizeof(type) > 8)])))
+
+#define syserror(format, ...)                           \
+	({                                              \
+		fprintf(stderr, format, ##__VA_ARGS__); \
+		(-errno);                               \
+	})
+
+#define syserror_set(__ret__, format, ...)                    \
+	({                                                    \
+		typeof(__ret__) __internal_ret__ = (__ret__); \
+		errno = labs(__ret__);                        \
+		fprintf(stderr, format, ##__VA_ARGS__);       \
+		__internal_ret__;                             \
+	})
+
+struct list {
+	void *elem;
+	struct list *next;
+	struct list *prev;
+};
+
+#define list_for_each(__iterator, __list) \
+	for (__iterator = (__list)->next; __iterator != __list; __iterator = __iterator->next)
+
+static inline void list_init(struct list *list)
+{
+	list->elem = NULL;
+	list->next = list->prev = list;
+}
+
+static inline int list_empty(const struct list *list)
+{
+	return list == list->next;
+}
+
+static inline void __list_add(struct list *new, struct list *prev, struct list *next)
+{
+	next->prev = new;
+	new->next = next;
+	new->prev = prev;
+	prev->next = new;
+}
+
+static inline void list_add_tail(struct list *head, struct list *list)
+{
+	__list_add(list, head->prev, head);
+}
+
+typedef enum idmap_type_t {
+	ID_TYPE_UID,
+	ID_TYPE_GID
+} idmap_type_t;
+
+struct id_map {
+	idmap_type_t map_type;
+	__u32 nsid;
+	__u32 hostid;
+	__u32 range;
+};
+
+static struct list active_map;
+
+static int add_map_entry(__u32 id_host,
+			 __u32 id_ns,
+			 __u32 range,
+			 idmap_type_t map_type)
+{
+	struct list *new_list = NULL;
+	struct id_map *newmap = NULL;
+
+	newmap = malloc(sizeof(*newmap));
+	if (!newmap)
+		return -ENOMEM;
+
+	new_list = malloc(sizeof(struct list));
+	if (!new_list) {
+		free(newmap);
+		return -ENOMEM;
+	}
+
+	*newmap = (struct id_map){
+		.hostid		= id_host,
+		.nsid		= id_ns,
+		.range		= range,
+		.map_type	= map_type,
+	};
+
+	new_list->elem = newmap;
+	list_add_tail(&active_map, new_list);
+	return 0;
+}
+
+static int parse_map(char *map)
+{
+	char types[2] = {'u', 'g'};
+	int ret;
+	__u32 id_host, id_ns, range;
+	char which;
+
+	if (!map)
+		return -1;
+
+	ret = sscanf(map, "%c:%u:%u:%u", &which, &id_ns, &id_host, &range);
+	if (ret != 4)
+		return -1;
+
+	if (which != 'b' && which != 'u' && which != 'g')
+		return -1;
+
+	for (int i = 0; i < 2; i++) {
+		idmap_type_t map_type;
+
+		if (which != types[i] && which != 'b')
+			continue;
+
+		if (types[i] == 'u')
+			map_type = ID_TYPE_UID;
+		else
+			map_type = ID_TYPE_GID;
+
+		ret = add_map_entry(id_host, id_ns, range, map_type);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int write_id_mapping(idmap_type_t map_type, pid_t pid, const char *buf, size_t buf_size)
+{
+	int fd = -EBADF, setgroups_fd = -EBADF;
+	int fret = -1;
+	int ret;
+	char path[STRLITERALLEN("/proc/") + INTTYPE_TO_STRLEN(pid_t) +
+		  STRLITERALLEN("/setgroups") + 1];
+
+	if (geteuid() != 0 && map_type == ID_TYPE_GID) {
+		ret = snprintf(path, sizeof(path), "/proc/%d/setgroups", pid);
+		if (ret < 0 || ret >= sizeof(path))
+			goto out;
+
+		setgroups_fd = open(path, O_WRONLY | O_CLOEXEC);
+		if (setgroups_fd < 0 && errno != ENOENT) {
+			syserror("Failed to open \"%s\"", path);
+			goto out;
+		}
+
+		if (setgroups_fd >= 0) {
+			ret = write_nointr(setgroups_fd, "deny\n", STRLITERALLEN("deny\n"));
+			if (ret != STRLITERALLEN("deny\n")) {
+				syserror("Failed to write \"deny\" to \"/proc/%d/setgroups\"", pid);
+				goto out;
+			}
+		}
+	}
+
+	ret = snprintf(path, sizeof(path), "/proc/%d/%cid_map", pid, map_type == ID_TYPE_UID ? 'u' : 'g');
+	if (ret < 0 || ret >= sizeof(path))
+		goto out;
+
+	fd = open(path, O_WRONLY | O_CLOEXEC);
+	if (fd < 0) {
+		syserror("Failed to open \"%s\"", path);
+		goto out;
+	}
+
+	ret = write_nointr(fd, buf, buf_size);
+	if (ret != buf_size) {
+		syserror("Failed to write %cid mapping to \"%s\"",
+			 map_type == ID_TYPE_UID ? 'u' : 'g', path);
+		goto out;
+	}
+
+	fret = 0;
+out:
+	if (fd >= 0)
+		close(fd);
+	if (setgroups_fd >= 0)
+		close(setgroups_fd);
+
+	return fret;
+}
+
+static int map_ids_from_idmap(struct list *idmap, pid_t pid)
+{
+	int fill, left;
+	char mapbuf[4096] = {};
+	bool had_entry = false;
+
+	for (idmap_type_t map_type = ID_TYPE_UID, u_or_g = 'u';
+	     map_type <= ID_TYPE_GID; map_type++, u_or_g = 'g') {
+		char *pos = mapbuf;
+		int ret;
+		struct list *iterator;
+
+
+		list_for_each(iterator, idmap) {
+			struct id_map *map = iterator->elem;
+			if (map->map_type != map_type)
+				continue;
+
+			had_entry = true;
+
+			left = 4096 - (pos - mapbuf);
+			fill = snprintf(pos, left, "%u %u %u\n", map->nsid, map->hostid, map->range);
+			/*
+			 * The kernel only takes <= 4k for writes to
+			 * /proc/<pid>/{g,u}id_map
+			 */
+			if (fill <= 0 || fill >= left)
+				return syserror_set(-E2BIG, "Too many %cid mappings defined", u_or_g);
+
+			pos += fill;
+		}
+		if (!had_entry)
+			continue;
+
+		ret = write_id_mapping(map_type, pid, mapbuf, pos - mapbuf);
+		if (ret < 0)
+			return syserror("Failed to write mapping: %s", mapbuf);
+
+		memset(mapbuf, 0, sizeof(mapbuf));
+	}
+
+	return 0;
+}
+
+static int get_userns_fd_from_idmap(struct list *idmap)
+{
+	int ret;
+	pid_t pid;
+	char path_ns[STRLITERALLEN("/proc/") + INTTYPE_TO_STRLEN(pid_t) +
+		  STRLITERALLEN("/ns/user") + 1];
+
+	pid = do_clone(get_userns_fd_cb, NULL, CLONE_NEWUSER | CLONE_NEWNS);
+	if (pid < 0)
+		return -errno;
+
+	ret = map_ids_from_idmap(idmap, pid);
+	if (ret < 0)
+		return ret;
+
+	ret = snprintf(path_ns, sizeof(path_ns), "/proc/%d/ns/user", pid);
+	if (ret < 0 || (size_t)ret >= sizeof(path_ns))
+		ret = -EIO;
+	else
+		ret = open(path_ns, O_RDONLY | O_CLOEXEC | O_NOCTTY);
+
+	(void)kill(pid, SIGKILL);
+	(void)wait_for_pid(pid);
+	return ret;
+}
+
+static inline bool strnequal(const char *str, const char *eq, size_t len)
+{
+	return strncmp(str, eq, len) == 0;
+}
+
+static void usage(void)
+{
+	const char *text = "\
+mount-idmapped --map-mount=<idmap> <source> <target>\n\
+\n\
+Create an idmapped mount of <source> at <target>\n\
+Options:\n\
+  --map-mount=<idmap>\n\
+	Specify an idmap for the <target> mount in the format\n\
+	<idmap-type>:<id-from>:<id-to>:<id-range>\n\
+	The <idmap-type> can be:\n\
+	\"b\" or \"both\"	-> map both uids and gids\n\
+	\"u\" or \"uid\"	-> map uids\n\
+	\"g\" or \"gid\"	-> map gids\n\
+	For example, specifying:\n\
+	both:1000:1001:1	-> map uid and gid 1000 to uid and gid 1001 in <target> and no other ids\n\
+	uid:20000:100000:1000	-> map uid 20000 to uid 100000, uid 20001 to uid 100001 [...] in <target>\n\
+	Currently up to 340 separate idmappings may be specified.\n\n\
+  --map-mount=/proc/<pid>/ns/user\n\
+	Specify a path to a user namespace whose idmap is to be used.\n\n\
+  --recursive\n\
+	Copy the whole mount tree from <source> and apply the idmap to everyone at <target>.\n\n\
+Examples:\n\
+  - Create an idmapped mount of /source on /target with both ('b') uids and gids mapped:\n\
+	mount-idmapped --map-mount b:0:10000:10000 /source /target\n\n\
+  - Create an idmapped mount of /source on /target with uids ('u') and gids ('g') mapped separately:\n\
+	mount-idmapped --map-mount u:0:10000:10000 g:0:20000:20000 /source /target\n\n\
+";
+	fprintf(stderr, "%s", text);
+	_exit(EXIT_SUCCESS);
+}
+
+#define exit_usage(format, ...)                         \
+	({                                              \
+		fprintf(stderr, format, ##__VA_ARGS__); \
+		usage();                                \
+	})
+
+#define exit_log(format, ...)                           \
+	({                                              \
+		fprintf(stderr, format, ##__VA_ARGS__); \
+		exit(EXIT_FAILURE);                     \
+	})
+
+static const struct option longopts[] = {
+	{"map-mount",	required_argument,	0,	'a'},
+	{"help",	no_argument,		0,	'c'},
+	{"recursive",	no_argument,		0,	'd'},
+	{ NULL,		0,			0,	0  },
+};
+
+int main(int argc, char *argv[])
+{
+	int fd_userns = -EBADF;
+	int index = 0;
+	const char *source = NULL, *target = NULL;
+	bool recursive = false;
+	int fd_tree, new_argc, ret;
+	char *const *new_argv;
+
+	list_init(&active_map);
+	while ((ret = getopt_long_only(argc, argv, "", longopts, &index)) != -1) {
+		switch (ret) {
+		case 'a':
+			if (strnequal(optarg, "/proc/", STRLITERALLEN("/proc/"))) {
+				fd_userns = open(optarg, O_RDONLY | O_CLOEXEC);
+				if (fd_userns < 0)
+					exit_log("%m - Failed top open user namespace path %s\n", optarg);
+				break;
+			}
+
+			ret = parse_map(optarg);
+			if (ret < 0)
+				exit_log("Failed to parse idmaps for mount\n");
+			break;
+		case 'd':
+			recursive = true;
+			break;
+		case 'c':
+			/* fallthrough */
+		default:
+			usage();
+		}
+	}
+
+	new_argv = &argv[optind];
+	new_argc = argc - optind;
+	if (new_argc < 2)
+		exit_usage("Missing source or target mountpoint\n\n");
+	source = new_argv[0];
+	target = new_argv[1];
+
+	fd_tree = sys_open_tree(-EBADF, source,
+			        OPEN_TREE_CLONE |
+			        OPEN_TREE_CLOEXEC |
+			        AT_EMPTY_PATH |
+			        (recursive ? AT_RECURSIVE : 0));
+	if (fd_tree < 0) {
+		exit_log("%m - Failed to open %s\n", source);
+		exit(EXIT_FAILURE);
+	}
+
+	if (!list_empty(&active_map) || fd_userns >= 0) {
+		struct mount_attr attr = {
+			.attr_set = MOUNT_ATTR_IDMAP,
+		};
+
+		if (fd_userns >= 0)
+			attr.userns_fd = fd_userns;
+		else
+			attr.userns_fd = get_userns_fd_from_idmap(&active_map);
+		if (attr.userns_fd < 0)
+			exit_log("%m - Failed to create user namespace\n");
+
+		ret = sys_mount_setattr(fd_tree, "", AT_EMPTY_PATH | AT_RECURSIVE,
+					&attr, sizeof(attr));
+		if (ret < 0)
+			exit_log("%m - Failed to change mount attributes\n");
+		close(attr.userns_fd);
+	}
+
+	ret = sys_move_mount(fd_tree, "", -EBADF, target,
+			     MOVE_MOUNT_F_EMPTY_PATH);
+	if (ret < 0)
+		exit_log("%m - Failed to attach mount to %s\n", target);
+	close(fd_tree);
+
+	exit(EXIT_SUCCESS);
+}
diff --git a/src/idmapped-mounts/utils.c b/src/idmapped-mounts/utils.c
index b27ba445..977443f1 100644
--- a/src/idmapped-mounts/utils.c
+++ b/src/idmapped-mounts/utils.c
@@ -88,7 +88,7 @@ pid_t do_clone(int (*fn)(void *), void *arg, int flags)
 #endif
 }
 
-static int get_userns_fd_cb(void *data)
+int get_userns_fd_cb(void *data)
 {
 	return kill(getpid(), SIGSTOP);
 }
diff --git a/src/idmapped-mounts/utils.h b/src/idmapped-mounts/utils.h
index 93425731..efbf3bc3 100644
--- a/src/idmapped-mounts/utils.h
+++ b/src/idmapped-mounts/utils.h
@@ -20,6 +20,7 @@
 #include "missing.h"
 
 extern pid_t do_clone(int (*fn)(void *), void *arg, int flags);
+extern int get_userns_fd_cb(void *data);
 extern int get_userns_fd(unsigned long nsid, unsigned long hostid,
 			 unsigned long range);
 extern ssize_t read_nointr(int fd, void *buf, size_t count);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v12 4/6] common/quota: move _qsetup() helper to common code
  2021-03-28 22:33 [PATCH v12 0/6] fstests: add idmapped mounts tests Christian Brauner
  2021-03-28 22:33 ` [PATCH v12 1/6] generic/631: add test for detached mount propagation Christian Brauner
  2021-03-28 22:33 ` [PATCH v12 3/6] common/rc: add _scratch_{u}mount_idmapped() helpers Christian Brauner
@ 2021-03-28 22:33 ` Christian Brauner
  2021-03-28 22:33 ` [PATCH v12 5/6] xfs/529: quotas and idmapped mounts Christian Brauner
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 24+ messages in thread
From: Christian Brauner @ 2021-03-28 22:33 UTC (permalink / raw)
  To: Eryu Guan, fstests, Christoph Hellwig
  Cc: Darrick J . Wong, David Howells, Christian Brauner

From: Christian Brauner <christian.brauner@ubuntu.com>

It's already used in two tests and will be used in a third.

Cc: Eryu Guan <guan@eryu.me>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Darrick J. Wong <djwong@kernel.org>
Cc: fstests@vger.kernel.org
Suggested-by: Eryu Guan <guan@eryu.me>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
/* v1 - v9 */
patch not present

/* v10 */
patch introduced

/* v11 */
unchanged

/* v12 */
unchanged
---
 common/quota  | 20 ++++++++++++++++++++
 tests/xfs/050 | 19 -------------------
 tests/xfs/299 | 19 -------------------
 3 files changed, 20 insertions(+), 38 deletions(-)

diff --git a/common/quota b/common/quota
index 1437d5f7..32a9a555 100644
--- a/common/quota
+++ b/common/quota
@@ -329,5 +329,25 @@ _report_quota_inodes() {
 	repquota $1 | egrep "^($qa_user|root|nobody)" | awk '{print $1, $6, $7, $8}' | sort -r
 }
 
+# Determine which type of quota we're using
+_qsetup()
+{
+	opt=$1
+	enforce=0
+	if [ $opt = "u" -o $opt = "uno" ]; then
+		type=u
+		eval `_choose_uid`
+	elif [ $opt = "g" -o $opt = "gno" ]; then
+		type=g
+		eval `_choose_gid`
+	elif [ $opt = "p" -o $opt = "pno" ]; then
+		type=p
+		eval `_choose_prid`
+	fi
+	[ $opt = "u" -o $opt = "g" -o $opt = "p" ] && enforce=1
+
+	echo "Using type=$type id=$id" >> $seqres.full
+}
+
 # make sure this script returns success
 /bin/true
diff --git a/tests/xfs/050 b/tests/xfs/050
index 1df97537..e7c81d0a 100755
--- a/tests/xfs/050
+++ b/tests/xfs/050
@@ -69,25 +69,6 @@ _filter_and_check_blks()
 	' | _filter_quota_report
 }
 
-_qsetup()
-{
-	opt=$1
-	enforce=0
-	if [ $opt = "u" -o $opt = "uno" ]; then
-		type=u
-		eval `_choose_uid`
-	elif [ $opt = "g" -o $opt = "gno" ]; then
-		type=g
-		eval `_choose_gid`
-	elif [ $opt = "p" -o $opt = "pno" ]; then
-		type=p
-		eval `_choose_prid`
-	fi
-	[ $opt = "u" -o $opt = "g" -o $opt = "p" ] && enforce=1
-
-	echo "Using type=$type id=$id" >> $seqres.full
-}
-
 _exercise()
 {
 	_scratch_mkfs_xfs | _filter_mkfs 2>$tmp.mkfs
diff --git a/tests/xfs/299 b/tests/xfs/299
index b862e67e..26b7fcfd 100755
--- a/tests/xfs/299
+++ b/tests/xfs/299
@@ -62,25 +62,6 @@ _filter_and_check_blks()
 	' | _filter_quota_report
 }
 
-_qsetup()
-{
-	opt=$1
-	enforce=0
-	if [ $opt = "u" -o $opt = "uno" ]; then
-		type=u
-		eval `_choose_uid`
-	elif [ $opt = "g" -o $opt = "gno" ]; then
-		type=g
-		eval `_choose_gid`
-	elif [ $opt = "p" -o $opt = "pno" ]; then
-		type=p
-		eval `_choose_prid`
-	fi
-	[ $opt = "u" -o $opt = "g" -o $opt = "p" ] && enforce=1
-
-	echo "Using type=$type id=$id" >> $seqres.full
-}
-
 _exercise()
 {
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v12 5/6] xfs/529: quotas and idmapped mounts
  2021-03-28 22:33 [PATCH v12 0/6] fstests: add idmapped mounts tests Christian Brauner
                   ` (2 preceding siblings ...)
  2021-03-28 22:33 ` [PATCH v12 4/6] common/quota: move _qsetup() helper to common code Christian Brauner
@ 2021-03-28 22:33 ` Christian Brauner
  2021-03-28 22:34 ` [PATCH v12 6/6] xfs/530: quotas on " Christian Brauner
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 24+ messages in thread
From: Christian Brauner @ 2021-03-28 22:33 UTC (permalink / raw)
  To: Eryu Guan, fstests, Christoph Hellwig
  Cc: Darrick J . Wong, David Howells, Christian Brauner

From: Christian Brauner <christian.brauner@ubuntu.com>

Test that xfs quota behave correctly on idmapped mounts.
Mount a scratch device with user and group quota support enabled. Create
directories "unmapped" and "idmapped". Create files in the unampped
mount and verify quota behavior. Create files through the idmapped mount
and verify identical behavior.

Cc: Eryu Guan <guan@eryu.me>
Cc: Darrick J. Wong <djwong@kernel.org>
Cc: fstests@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
/* v1 - v8 */
patch not present

/* v9 */
- Christian Brauner <christian.brauner@ubuntu.com>:
  - Rebased on current master.

/* v10 */
- Eryu Guan <guan@eryu.me>:
  - Remove leading "_" from local helpers.
  - Remove redundant "-q" option from umount -l calls.
  - Use wipe_mount() in a few more places.

/* v11 */
- Amir Goldstein <amir73il@gmail.com>:
  - Add a dedicated "idmapped" tag for idmapped mounts tests.

/* v12 */
- Eryu Guan <guan@eryu.me>:
  - Don't use lazy umount if not required.
---
 tests/xfs/529     | 377 ++++++++++++++++++++++++++
 tests/xfs/529.out | 657 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/group   |   1 +
 3 files changed, 1035 insertions(+)
 create mode 100644 tests/xfs/529
 create mode 100644 tests/xfs/529.out

diff --git a/tests/xfs/529 b/tests/xfs/529
new file mode 100644
index 00000000..a5d92314
--- /dev/null
+++ b/tests/xfs/529
@@ -0,0 +1,377 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2021 Christian Brauner <christian.brauner@ubuntu.com>
+# All Rights Reserved.
+#
+# FS QA Test No. 529
+#
+# Exercise basic xfs_quota functionality (user/group/project quota)
+# Use of "sync" mount option here is an attempt to get deterministic
+# allocator behaviour.
+#
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+wipe_mounts()
+{
+	umount "${SCRATCH_MNT}/idmapped" >/dev/null 2>&1
+	_scratch_unmount >/dev/null 2>&1
+}
+
+_cleanup()
+{
+	cd /
+	wipe_mounts
+	rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/quota
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# real QA test starts here
+_supported_fs xfs
+_require_idmapped_mounts
+_require_test_program "idmapped-mounts/mount-idmapped"
+_require_scratch
+_require_xfs_quota
+_require_user fsgqa
+_require_user fsgqa2
+_require_group fsgqa
+_require_group fsgqa2
+
+_scratch_mkfs_xfs >>$seqres.full 2>&1
+
+uqid=`id -u fsgqa`
+gqid=`id -g fsgqa`
+
+uqid2=`id -u fsgqa2`
+gqid2=`id -g fsgqa2`
+
+pqid=10
+cat >$tmp.projects <<EOF
+$pqid:$SCRATCH_MNT
+EOF
+
+cat >$tmp.projid <<EOF
+root:0
+fsgqa:$pqid
+EOF
+
+create_files_unmapped()
+{
+	local bs=$1
+	local inum=$2
+
+	echo "Using type=$type id=$id" >> $seqres.full
+
+	for ((i=0; i<$((inum-1)); i++)); do
+		_file_as_id $SCRATCH_MNT/unmapped/inode$i $id $type 1024 0
+	done
+
+	_file_as_id $SCRATCH_MNT/unmapped/block $id $type $bs 1
+}
+
+create_files_idmapped()
+{
+	local bs=$1
+	local inum=$2
+
+	echo "Using type=$type id=$id2" >> $seqres.full
+
+	for ((i=0; i<$((inum-1)); i++)); do
+		_file_as_id $SCRATCH_MNT/idmapped/inode$i $id2 $type 1024 0
+	done
+
+	_file_as_id $SCRATCH_MNT/idmapped/block $id2 $type $bs 1
+}
+
+clean_files()
+{
+	rm -rf $SCRATCH_MNT/unmapped 2>/dev/null
+	rm -rf $SCRATCH_MNT/idmapped 2>/dev/null
+	rm -rf $tmp.quot 2>/dev/null
+	rm -rf $tmp.quota 2>/dev/null
+}
+
+filter_quot()
+{
+	_filter_quota | grep -v "root \|\#0 " \
+		| sed -e '/#[0-9]*/s/#[0-9]*/#ID/g'
+}
+
+filter_report()
+{
+	_filter_quota | grep -v "^root \|^\#0 " \
+		| sed -e '/^#[0-9]*/s/^#[0-9]*/#ID/g'
+}
+
+filter_quota()
+{
+	_filter_quota | sed -e "/Disk quotas for/s/([0-9]*)/(ID)/g" \
+			    -e "/Disk quotas for/s/#[0-9]*/#ID/g"
+}
+
+filter_state()
+{
+	_filter_quota | sed -e "s/Inode: #[0-9]* (0 blocks, 0 extents)/Inode: #[INO] (0 blocks, 0 extents)/g" \
+			    -e "s/Inode: #[0-9]* ([0-9]* blocks, [0-9]* extents)/Inode: #[INO] (X blocks, Y extents)/g" \
+			    -e "/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/s/ [0-9][0-9]:[0-9][0-9]:[0-9][0-9]//g" \
+			    -e '/max warnings:/d'
+}
+
+test_quot()
+{
+	local opt="$*"
+
+	echo "checking quot command (type=$type)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "quot -$type $opt -bi" $SCRATCH_MNT | filter_quot
+}
+
+test_report()
+{
+	local opt="$*"
+
+	echo "checking report command (type=$type)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "report -$type $opt -bi" \
+			$SCRATCH_MNT | filter_report
+}
+
+test_quota()
+{
+	local opt="$*"
+
+	echo "checking quota command (type=$type)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "quota -$type $opt -bi $id" \
+			$SCRATCH_MNT | filter_quota
+}
+
+test_limit()
+{
+	local bs=$1
+	local bh=$2
+	local is=$3
+	local ih=$4
+
+	echo "checking limit command (type=$type, bsoft=$bs, bhard=$bh, isoft=$is, ihard=$ih)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "limit -$type bsoft=$bs bhard=$bh fsgqa" \
+			-c "limit -$type isoft=$is ihard=$ih fsgqa" \
+			$SCRATCH_MNT
+
+	# let the timer day transition happen
+	sleep 2
+}
+
+test_timer()
+{
+	echo "checking timer command (type=$type)"
+	# set 3days+1h for time won't become 2days soon
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "timer -$type -bi 73h" \
+			$SCRATCH_MNT | _filter_scratch
+}
+
+test_disable()
+{
+	echo "checking disable command (type=$type)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "disable -$type -v" \
+			$SCRATCH_MNT | filter_state
+}
+
+test_enable()
+{
+	echo "checking enable command (type=$type)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "enable -$type -v" $SCRATCH_MNT | filter_state
+}
+
+test_off()
+{
+	echo "checking off command (type=$type)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "off -$type -v" $SCRATCH_MNT | _filter_scratch
+}
+
+test_remove()
+{
+	echo "checking remove command (type=$type)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "remove -$type -v" \
+			$SCRATCH_MNT | _filter_scratch
+}
+
+test_state()
+{
+	echo "checking state command (type=$type)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "state -$type" $SCRATCH_MNT | filter_state
+}
+
+test_dump()
+{
+	echo "checking dump command (type=$type)"
+	rm -f $tmp.backup 2>>/dev/null
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "dump -$type -f $tmp.backup" \
+			$SCRATCH_MNT | _filter_scratch
+}
+
+test_restore()
+{
+	echo "checking restore command (type=$type)"
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+			-c "restore -$type -f $tmp.backup" \
+			$SCRATCH_MNT | _filter_scratch
+}
+
+wipe_scratch()
+{
+	wipe_mounts
+	_scratch_mkfs_xfs >>$seqres.full 2>&1
+}
+
+qmount_idmapped()
+{
+	wipe_mounts
+	_try_scratch_mount || _fail "qmount failed"
+
+	mkdir -p "${SCRATCH_MNT}/unmapped"
+	mkdir -p "${SCRATCH_MNT}/idmapped"
+
+	$here/src/idmapped-mounts/mount-idmapped \
+		--map-mount b:$id:$id2:1 \
+		--map-mount b:0:0:1 \
+		"$SCRATCH_MNT/unmapped" "$SCRATCH_MNT/idmapped" || _fail "mount-idmapped failed"
+
+	chmod ugo+rwx $SCRATCH_MNT
+	chmod ugo+rwx $SCRATCH_MNT/unmapped
+	chmod ugo+rwx $SCRATCH_MNT/idmapped
+}
+
+test_xfs_quota()
+{
+	# init quota
+	echo "init quota limit and timer, and dump it"
+	if [ "$idmapped" -eq 1 ]; then
+		echo "create_files_idmapped 1024k 15"; create_files_idmapped 1024k 15
+	else
+		echo "create_files_unmapped 1024k 15"; create_files_unmapped 1024k 15
+	fi
+	echo "quota remount"; qmount_idmapped
+	echo ; test_quot
+	echo ; test_timer
+	echo ; test_limit 512k 2048k 10 20
+	echo ; test_dump
+
+	# report options test
+	echo "report options test"
+	echo ; test_report
+	echo "-N option"; test_report -N
+	echo "-L -U options"; test_report -L $id -U $id
+	echo "-t option"; test_report -t
+	echo "-n option"; test_report -n
+	echo "-h option"; test_report -h
+
+	# quot options test
+	echo "quot options test"
+	echo ; test_quot
+	echo "-f option"; test_quot -f $tmp.quot
+	cat $tmp.quot | filter_quot
+	echo "-n option"; test_quot -n
+
+	# quota options test
+	echo ; test_quota
+	echo "-f option"; test_quota -f $tmp.quota
+	cat $tmp.quota | filter_quota
+	echo "-N option"; test_quota -N
+	echo "-n option"; test_quota -n
+	echo "-h option"; test_quota -h
+
+	# disable/enable test
+	echo "disable quota"
+	echo ; test_disable
+	echo ; test_report -N
+	echo "expect a remove error at here"; test_remove
+	echo ; test_enable
+	echo ; test_report -N
+
+	# off and remove test
+	echo "off and remove test"
+	echo ; test_limit 100m 100m 100 100
+	echo ; test_quota -N
+	echo ; test_off
+	echo ; test_state
+	echo ; test_remove
+	echo ; test_report -N
+	echo "quota remount"; qmount_idmapped
+	echo ; test_report -N
+
+	# restore test
+	echo "restore quota"
+	echo ; test_restore
+	echo ; test_report -N
+	echo ; test_state
+	echo "cleanup files"; clean_files
+}
+
+echo "----------------------- uquota,sync,unmapped ---------------------------"
+wipe_scratch
+_qmount_option "uquota,sync"
+type=u
+id=$uqid
+id2=$uqid2
+idmapped=0
+qmount_idmapped
+test_xfs_quota
+
+echo "----------------------- uquota,sync,idmapped ---------------------------"
+wipe_scratch
+_qmount_option "uquota,sync"
+type=u
+id=$uqid
+id2=$uqid2
+idmapped=1
+qmount_idmapped
+test_xfs_quota
+
+echo "----------------------- gquota,sync,unmapped ---------------------------"
+wipe_scratch
+_qmount_option "gquota,sync"
+type=g
+id=$gqid
+id2=$gqid2
+idmapped=0
+qmount_idmapped
+test_xfs_quota
+
+echo "----------------------- gquota,sync,idmapped ---------------------------"
+wipe_scratch
+_qmount_option "gquota,sync"
+type=g
+id=$gqid
+id2=$gqid2
+idmapped=1
+qmount_idmapped
+test_xfs_quota
+
+wipe_mounts
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/529.out b/tests/xfs/529.out
new file mode 100644
index 00000000..7d2cd96d
--- /dev/null
+++ b/tests/xfs/529.out
@@ -0,0 +1,657 @@
+QA output created by 529
+----------------------- uquota,sync,unmapped ---------------------------
+init quota limit and timer, and dump it
+create_files_unmapped 1024k 15
+quota remount
+
+checking quot command (type=u)
+SCRATCH_DEV (SCRATCH_MNT) User:
+ 1024 15 fsgqa 
+
+checking timer command (type=u)
+
+checking limit command (type=u, bsoft=512k, bhard=2048k, isoft=10, ihard=20)
+
+checking dump command (type=u)
+report options test
+
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-N option
+checking report command (type=u)
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-L -U options
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-t option
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-n option
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-h option
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace 
+---------- --------------------------------- --------------------------------- 
+fsgqa 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days]
+
+quot options test
+
+checking quot command (type=u)
+SCRATCH_DEV (SCRATCH_MNT) User:
+ 1024 15 fsgqa 
+-f option
+checking quot command (type=u)
+SCRATCH_DEV (SCRATCH_MNT) User:
+ 1024 15 fsgqa 
+-n option
+checking quot command (type=u)
+SCRATCH_DEV (SCRATCH_MNT) User:
+ 1024 15 #ID 
+
+checking quota command (type=u)
+Disk quotas for User fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-f option
+checking quota command (type=u)
+Disk quotas for User fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-N option
+checking quota command (type=u)
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-n option
+checking quota command (type=u)
+Disk quotas for User #ID (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-h option
+checking quota command (type=u)
+Disk quotas for User fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+disable quota
+
+checking disable command (type=u)
+User quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: OFF
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [3 days]
+Inodes grace time: [3 days]
+Realtime Blocks grace time: [7 days]
+
+checking report command (type=u)
+fsgqa 1024 512 2048 00 [--------] 15 10 20 00 [--------]
+
+expect a remove error at here
+checking remove command (type=u)
+XFS_QUOTARM: Invalid argument
+
+checking enable command (type=u)
+User quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: ON
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [3 days]
+Inodes grace time: [3 days]
+Realtime Blocks grace time: [7 days]
+
+checking report command (type=u)
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+off and remove test
+
+checking limit command (type=u, bsoft=100m, bhard=100m, isoft=100, ihard=100)
+
+checking quota command (type=u)
+SCRATCH_DEV 1024 102400 102400 00 [--------] 15 100 100 00 [--------] SCRATCH_MNT
+
+checking off command (type=u)
+User quota are not enabled on SCRATCH_DEV
+
+checking state command (type=u)
+
+checking remove command (type=u)
+User quota are not enabled on SCRATCH_DEV
+
+checking report command (type=u)
+
+quota remount
+
+checking report command (type=u)
+fsgqa 1024 0 0 00 [--------] 15 0 0 00 [--------]
+
+restore quota
+
+checking restore command (type=u)
+
+checking report command (type=u)
+fsgqa 1024 512 2048 00 [7 days] 15 10 20 00 [7 days]
+
+
+checking state command (type=u)
+User quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: ON
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [7 days]
+Inodes grace time: [7 days]
+Realtime Blocks grace time: [7 days]
+cleanup files
+----------------------- uquota,sync,idmapped ---------------------------
+init quota limit and timer, and dump it
+create_files_idmapped 1024k 15
+quota remount
+
+checking quot command (type=u)
+SCRATCH_DEV (SCRATCH_MNT) User:
+ 1024 15 fsgqa 
+
+checking timer command (type=u)
+
+checking limit command (type=u, bsoft=512k, bhard=2048k, isoft=10, ihard=20)
+
+checking dump command (type=u)
+report options test
+
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-N option
+checking report command (type=u)
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-L -U options
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-t option
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-n option
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-h option
+checking report command (type=u)
+User quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+User ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace 
+---------- --------------------------------- --------------------------------- 
+fsgqa 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days]
+
+quot options test
+
+checking quot command (type=u)
+SCRATCH_DEV (SCRATCH_MNT) User:
+ 1024 15 fsgqa 
+-f option
+checking quot command (type=u)
+SCRATCH_DEV (SCRATCH_MNT) User:
+ 1024 15 fsgqa 
+-n option
+checking quot command (type=u)
+SCRATCH_DEV (SCRATCH_MNT) User:
+ 1024 15 #ID 
+
+checking quota command (type=u)
+Disk quotas for User fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-f option
+checking quota command (type=u)
+Disk quotas for User fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-N option
+checking quota command (type=u)
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-n option
+checking quota command (type=u)
+Disk quotas for User #ID (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-h option
+checking quota command (type=u)
+Disk quotas for User fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+disable quota
+
+checking disable command (type=u)
+User quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: OFF
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [3 days]
+Inodes grace time: [3 days]
+Realtime Blocks grace time: [7 days]
+
+checking report command (type=u)
+fsgqa 1024 512 2048 00 [--------] 15 10 20 00 [--------]
+
+expect a remove error at here
+checking remove command (type=u)
+XFS_QUOTARM: Invalid argument
+
+checking enable command (type=u)
+User quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: ON
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [3 days]
+Inodes grace time: [3 days]
+Realtime Blocks grace time: [7 days]
+
+checking report command (type=u)
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+off and remove test
+
+checking limit command (type=u, bsoft=100m, bhard=100m, isoft=100, ihard=100)
+
+checking quota command (type=u)
+SCRATCH_DEV 1024 102400 102400 00 [--------] 15 100 100 00 [--------] SCRATCH_MNT
+
+checking off command (type=u)
+User quota are not enabled on SCRATCH_DEV
+
+checking state command (type=u)
+
+checking remove command (type=u)
+User quota are not enabled on SCRATCH_DEV
+
+checking report command (type=u)
+
+quota remount
+
+checking report command (type=u)
+fsgqa 1024 0 0 00 [--------] 15 0 0 00 [--------]
+
+restore quota
+
+checking restore command (type=u)
+
+checking report command (type=u)
+fsgqa 1024 512 2048 00 [7 days] 15 10 20 00 [7 days]
+
+
+checking state command (type=u)
+User quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: ON
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [7 days]
+Inodes grace time: [7 days]
+Realtime Blocks grace time: [7 days]
+cleanup files
+----------------------- gquota,sync,unmapped ---------------------------
+init quota limit and timer, and dump it
+create_files_unmapped 1024k 15
+quota remount
+
+checking quot command (type=g)
+SCRATCH_DEV (SCRATCH_MNT) Group:
+ 1024 15 fsgqa 
+
+checking timer command (type=g)
+
+checking limit command (type=g, bsoft=512k, bhard=2048k, isoft=10, ihard=20)
+
+checking dump command (type=g)
+report options test
+
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-N option
+checking report command (type=g)
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-L -U options
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-t option
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-n option
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-h option
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace 
+---------- --------------------------------- --------------------------------- 
+fsgqa 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days]
+
+quot options test
+
+checking quot command (type=g)
+SCRATCH_DEV (SCRATCH_MNT) Group:
+ 1024 15 fsgqa 
+-f option
+checking quot command (type=g)
+SCRATCH_DEV (SCRATCH_MNT) Group:
+ 1024 15 fsgqa 
+-n option
+checking quot command (type=g)
+SCRATCH_DEV (SCRATCH_MNT) Group:
+ 1024 15 #ID 
+
+checking quota command (type=g)
+Disk quotas for Group fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-f option
+checking quota command (type=g)
+Disk quotas for Group fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-N option
+checking quota command (type=g)
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-n option
+checking quota command (type=g)
+Disk quotas for Group #ID (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-h option
+checking quota command (type=g)
+Disk quotas for Group fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+disable quota
+
+checking disable command (type=g)
+Group quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: OFF
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [3 days]
+Inodes grace time: [3 days]
+Realtime Blocks grace time: [7 days]
+
+checking report command (type=g)
+fsgqa 1024 512 2048 00 [--------] 15 10 20 00 [--------]
+
+expect a remove error at here
+checking remove command (type=g)
+XFS_QUOTARM: Invalid argument
+
+checking enable command (type=g)
+Group quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: ON
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [3 days]
+Inodes grace time: [3 days]
+Realtime Blocks grace time: [7 days]
+
+checking report command (type=g)
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+off and remove test
+
+checking limit command (type=g, bsoft=100m, bhard=100m, isoft=100, ihard=100)
+
+checking quota command (type=g)
+SCRATCH_DEV 1024 102400 102400 00 [--------] 15 100 100 00 [--------] SCRATCH_MNT
+
+checking off command (type=g)
+Group quota are not enabled on SCRATCH_DEV
+
+checking state command (type=g)
+
+checking remove command (type=g)
+Group quota are not enabled on SCRATCH_DEV
+
+checking report command (type=g)
+
+quota remount
+
+checking report command (type=g)
+fsgqa 1024 0 0 00 [--------] 15 0 0 00 [--------]
+
+restore quota
+
+checking restore command (type=g)
+
+checking report command (type=g)
+fsgqa 1024 512 2048 00 [7 days] 15 10 20 00 [7 days]
+
+
+checking state command (type=g)
+Group quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: ON
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [7 days]
+Inodes grace time: [7 days]
+Realtime Blocks grace time: [7 days]
+cleanup files
+----------------------- gquota,sync,idmapped ---------------------------
+init quota limit and timer, and dump it
+create_files_idmapped 1024k 15
+quota remount
+
+checking quot command (type=g)
+SCRATCH_DEV (SCRATCH_MNT) Group:
+ 1024 15 fsgqa 
+
+checking timer command (type=g)
+
+checking limit command (type=g, bsoft=512k, bhard=2048k, isoft=10, ihard=20)
+
+checking dump command (type=g)
+report options test
+
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-N option
+checking report command (type=g)
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-L -U options
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-t option
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-n option
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/ Grace 
+---------- -------------------------------------------------- -------------------------------------------------- 
+#ID 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+-h option
+checking report command (type=g)
+Group quota on SCRATCH_MNT (SCRATCH_DEV)
+ Blocks Inodes 
+Group ID Used Soft Hard Warn/Grace Used Soft Hard Warn/Grace 
+---------- --------------------------------- --------------------------------- 
+fsgqa 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days]
+
+quot options test
+
+checking quot command (type=g)
+SCRATCH_DEV (SCRATCH_MNT) Group:
+ 1024 15 fsgqa 
+-f option
+checking quot command (type=g)
+SCRATCH_DEV (SCRATCH_MNT) Group:
+ 1024 15 fsgqa 
+-n option
+checking quot command (type=g)
+SCRATCH_DEV (SCRATCH_MNT) Group:
+ 1024 15 #ID 
+
+checking quota command (type=g)
+Disk quotas for Group fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-f option
+checking quota command (type=g)
+Disk quotas for Group fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-N option
+checking quota command (type=g)
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-n option
+checking quota command (type=g)
+Disk quotas for Group #ID (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1024 512 2048 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+-h option
+checking quota command (type=g)
+Disk quotas for Group fsgqa (ID)
+Filesystem Blocks Quota Limit Warn/Time Files Quota Limit Warn/Time Mounted on
+SCRATCH_DEV 1M 512K 2M 00 [3 days] 15 10 20 00 [3 days] SCRATCH_MNT
+disable quota
+
+checking disable command (type=g)
+Group quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: OFF
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [3 days]
+Inodes grace time: [3 days]
+Realtime Blocks grace time: [7 days]
+
+checking report command (type=g)
+fsgqa 1024 512 2048 00 [--------] 15 10 20 00 [--------]
+
+expect a remove error at here
+checking remove command (type=g)
+XFS_QUOTARM: Invalid argument
+
+checking enable command (type=g)
+Group quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: ON
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [3 days]
+Inodes grace time: [3 days]
+Realtime Blocks grace time: [7 days]
+
+checking report command (type=g)
+fsgqa 1024 512 2048 00 [3 days] 15 10 20 00 [3 days]
+
+off and remove test
+
+checking limit command (type=g, bsoft=100m, bhard=100m, isoft=100, ihard=100)
+
+checking quota command (type=g)
+SCRATCH_DEV 1024 102400 102400 00 [--------] 15 100 100 00 [--------] SCRATCH_MNT
+
+checking off command (type=g)
+Group quota are not enabled on SCRATCH_DEV
+
+checking state command (type=g)
+
+checking remove command (type=g)
+Group quota are not enabled on SCRATCH_DEV
+
+checking report command (type=g)
+
+quota remount
+
+checking report command (type=g)
+fsgqa 1024 0 0 00 [--------] 15 0 0 00 [--------]
+
+restore quota
+
+checking restore command (type=g)
+
+checking report command (type=g)
+fsgqa 1024 512 2048 00 [7 days] 15 10 20 00 [7 days]
+
+
+checking state command (type=g)
+Group quota state on SCRATCH_MNT (SCRATCH_DEV)
+ Accounting: ON
+ Enforcement: ON
+ Inode: #[INO] (X blocks, Y extents)
+Blocks grace time: [7 days]
+Inodes grace time: [7 days]
+Realtime Blocks grace time: [7 days]
+cleanup files
diff --git a/tests/xfs/group b/tests/xfs/group
index 288b916d..03b447c7 100644
--- a/tests/xfs/group
+++ b/tests/xfs/group
@@ -505,3 +505,4 @@
 526 auto quick mkfs
 527 auto quick quota
 528 auto quick rw realtime
+529 auto quick quota idmapped
-- 
2.27.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v12 6/6] xfs/530: quotas on idmapped mounts
  2021-03-28 22:33 [PATCH v12 0/6] fstests: add idmapped mounts tests Christian Brauner
                   ` (3 preceding siblings ...)
  2021-03-28 22:33 ` [PATCH v12 5/6] xfs/529: quotas and idmapped mounts Christian Brauner
@ 2021-03-28 22:34 ` Christian Brauner
       [not found] ` <20210328223400.1800301-3-brauner@kernel.org>
  2021-04-11 14:37 ` [PATCH v12 0/6] fstests: add idmapped mounts tests Eryu Guan
  6 siblings, 0 replies; 24+ messages in thread
From: Christian Brauner @ 2021-03-28 22:34 UTC (permalink / raw)
  To: Eryu Guan, fstests, Christoph Hellwig
  Cc: Darrick J . Wong, David Howells, Christian Brauner

From: Christian Brauner <christian.brauner@ubuntu.com>

This is basically a re-implementation of xfs/050 but each file creation
call is done through an idmapped mount which verifies that the semantics
are identical even when the mount is idmapped.

Cc: Eryu Guan <guan@eryu.me>
Cc: Darrick J. Wong <djwong@kernel.org>
Cc: fstests@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
/* v1 - v8 */
patch not present

/* v9 */
- Christian Brauner <christian.brauner@ubuntu.com>:
  - Rebased onto current master.

/* v10 */
- Eryu Guan <guan@eryu.me>:
  - Remove leading "_" from local helpers.
  - Use newly introduced _scratch_{u}mount_idmapped() helpers

/* v11 */
- Amir Goldstein <amir73il@gmail.com>:
  - Add a dedicated "idmapped" tag for idmapped mounts tests.

/* v12 */
unchanged
---
 tests/xfs/530     | 212 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/530.out | 129 ++++++++++++++++++++++++++++
 tests/xfs/group   |   1 +
 3 files changed, 342 insertions(+)
 create mode 100644 tests/xfs/530
 create mode 100644 tests/xfs/530.out

diff --git a/tests/xfs/530 b/tests/xfs/530
new file mode 100644
index 00000000..7d2e8771
--- /dev/null
+++ b/tests/xfs/530
@@ -0,0 +1,212 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2021 Christian Brauner <christian.brauner@ubuntu.com>
+# All Rights Reserved.
+#
+# FS QA Test No. 530
+#
+# Exercises basic XFS quota functionality
+#       uquota, gquota, uqnoenforce, gqnoenforce
+#
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/quota
+
+_cleanup()
+{
+	cd /
+	_scratch_unmount 2>/dev/null
+	rm -f $tmp.*
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# real QA test starts here
+_supported_fs xfs
+
+cp /dev/null $seqres.full
+chmod a+rwx $seqres.full	# arbitrary users will write here
+
+_require_scratch
+_require_xfs_quota
+_require_user fsgqa
+_require_test_program "idmapped-mounts/mount-idmapped"
+
+_scratch_mkfs >/dev/null 2>&1
+_scratch_mount
+bsize=$(_get_file_block_size $SCRATCH_MNT)
+_scratch_unmount
+
+bsoft=$(( 200 * $bsize ))
+bhard=$(( 1000 * $bsize ))
+isoft=4
+ihard=10
+
+# The actual point at which limit enforcement takes place for the
+# hard block limit is variable depending on filesystem blocksize,
+# and iosize.  What we want to test is that the limit is enforced
+# (ie. blksize less than limit but not unduly less - ~85% is kind)
+# nowadays we actually get much closer to the limit before EDQUOT.
+#
+_filter_and_check_blks()
+{
+	perl -npe '
+		if (/^\#'$id'\s+(\d+)/ && '$enforce') {
+			$maximum = '$bhard';
+			$minimum = '$bhard' * 85/100;
+			$used = $1 * 1024;
+			if (($used < $minimum || $used > $maximum) && '$noextsz') {
+				printf(" URK %d: %d is out of range! [%d,%d]\n",
+					'$id', $used, $minimum, $maximum);
+			}
+			s/^(\#'$id'\s+)(\d+)/\1 =OK=/g;
+		}
+	' | _filter_quota_report
+}
+
+run_tests()
+{
+	_scratch_mkfs_xfs | _filter_mkfs 2>$tmp.mkfs
+	cat $tmp.mkfs >>$seqres.full
+
+	# keep the blocksize and data size for dd later
+	. $tmp.mkfs
+
+	_qmount
+
+	# Figure out whether we're doing large allocations
+	# (bail out if they're so large they stuff the test up)
+	_test_inode_flag extsz-inherit $SCRATCH_MNT
+	noextsz=$?
+	extsize=`_test_inode_extsz $SCRATCH_MNT`
+	[ $extsize -ge 512000 ] && \
+		_notrun "Extent size hint is too large ($extsize bytes)"
+
+	_qsetup $1
+
+	echo "Using type=$type id=$id" >>$seqres.full
+
+	$XFS_QUOTA_PROG -x -c "warn -$type 65535 -d" $SCRATCH_DEV
+
+	echo
+	echo "*** report no quota settings" | tee -a $seqres.full
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+		-c "repquota -birnN -$type" $SCRATCH_DEV |
+		_filter_quota_report | LC_COLLATE=POSIX sort -ru
+
+	echo
+	echo "*** report initial settings" | tee -a $seqres.full
+	_scratch_mount_idmapped $type $id
+	_file_as_id $SCRATCH_MNT/initme 0 $type 1024 0
+	_scratch_umount_idmapped
+	echo "ls -l $SCRATCH_MNT" >>$seqres.full
+	ls -l $SCRATCH_MNT >>$seqres.full
+	$XFS_QUOTA_PROG -D $tmp.projects -P $temp.projid -x \
+		-c "limit -$type bsoft=${bsoft} bhard=${bhard} $id" \
+		-c "limit -$type isoft=$isoft ihard=$ihard $id" \
+		$SCRATCH_DEV
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+		-c "repquota -birnN -$type" $SCRATCH_DEV |
+		_filter_quota_report | LC_COLLATE=POSIX sort -ru
+
+	echo
+	echo "*** push past the soft inode limit" | tee -a $seqres.full
+	_scratch_mount_idmapped $type $id
+	_file_as_id $SCRATCH_MNT/softie1 0 $type 1024 0
+	_file_as_id $SCRATCH_MNT/softie2 0 $type 1024 0
+	_file_as_id $SCRATCH_MNT/softie3 0 $type 1024 0
+	_file_as_id $SCRATCH_MNT/softie4 0 $type 1024 0
+	_scratch_umount_idmapped
+	_qmount
+	$XFS_QUOTA_PROG -x -c "warn -i -$type 0 $id" $SCRATCH_DEV
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+		-c "repquota -birnN -$type" $SCRATCH_DEV |
+		_filter_quota_report | LC_COLLATE=POSIX sort -ru
+
+	echo
+	echo "*** push past the soft block limit" | tee -a $seqres.full
+	_scratch_mount_idmapped $type $id
+	_file_as_id $SCRATCH_MNT/softie 0 $type $bsize 300
+	_scratch_umount_idmapped
+	_qmount
+	$XFS_QUOTA_PROG -x -c "warn -i -$type 0 $id" \
+		-c "warn -b -$type 0 $id" $SCRATCH_DEV
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+		-c "repquota -birnN -$type" $SCRATCH_DEV |
+		_filter_quota_report | LC_COLLATE=POSIX sort -ru
+
+	echo
+	# Note: for quota accounting (not enforcement), EDQUOT is not expected
+	echo "*** push past the hard inode limit (expect EDQUOT)" | tee -a $seqres.full
+	for i in 1 2 3 4 5 6 7 8 9 10 11 12
+	do
+		_scratch_mount_idmapped $type $id
+		_file_as_id $SCRATCH_MNT/hard$i 0 $type 1024 0
+		_scratch_umount_idmapped
+	done
+	_qmount
+	$XFS_QUOTA_PROG -x  -c "warn -b -$type 0 $id" \
+		-c "warn -i -$type 0 $id" $SCRATCH_DEV
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+		-c "repquota -birnN -$type" $SCRATCH_DEV |
+		_filter_quota_report | LC_COLLATE=POSIX sort -ru
+
+	echo
+	# Note: for quota accounting (not enforcement), EDQUOT is not expected
+	echo "*** push past the hard block limit (expect EDQUOT)" | tee -a $seqres.full
+	_scratch_mount_idmapped $type $id
+	_file_as_id $SCRATCH_MNT/softie 0 $type $bsize 1200
+	_scratch_umount_idmapped
+	echo "ls -l $SCRATCH_MNT" >>$seqres.full
+	ls -l $SCRATCH_MNT >>$seqres.full
+	_qmount
+	$XFS_QUOTA_PROG -x -c "warn -b -$type 0 $id" $SCRATCH_DEV
+	$XFS_QUOTA_PROG -D $tmp.projects -P $tmp.projid -x \
+		-c "repquota -birnN -$type" $SCRATCH_DEV |
+		_filter_and_check_blks | LC_COLLATE=POSIX sort -ru
+
+	echo
+	echo "*** unmount"
+	_scratch_unmount
+
+}
+
+cat >$tmp.projects <<EOF
+1:$SCRATCH_MNT
+EOF
+
+cat >$tmp.projid <<EOF
+root:0
+scrach:1
+EOF
+
+projid_file="$tmp.projid"
+
+echo "*** user"
+_qmount_option "uquota"
+run_tests u
+
+echo "*** group"
+_qmount_option "gquota"
+run_tests g
+
+echo "*** uqnoenforce"
+_qmount_option "uqnoenforce"
+run_tests uno
+
+echo "*** gqnoenforce"
+_qmount_option "gqnoenforce"
+run_tests gno
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/530.out b/tests/xfs/530.out
new file mode 100644
index 00000000..39266b38
--- /dev/null
+++ b/tests/xfs/530.out
@@ -0,0 +1,129 @@
+QA output created by 530
+*** user
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data     = bsize=XXX blocks=XXX, imaxpct=PCT
+         = sunit=XXX swidth=XXX, unwritten=X
+naming   =VERN bsize=XXX
+log      =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+
+*** report no quota settings
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+
+*** report initial settings
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 0 200 1000 00 [--------] 1 4 10 00 [--------] 0 0 0 00 [--------]
+
+*** push past the soft inode limit
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 0 200 1000 00 [--------] 5 4 10 00 [7 days] 0 0 0 00 [--------]
+
+*** push past the soft block limit
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 300 200 1000 00 [7 days] 6 4 10 00 [7 days] 0 0 0 00 [--------]
+
+*** push past the hard inode limit (expect EDQUOT)
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 300 200 1000 00 [7 days] 10 4 10 00 [7 days] 0 0 0 00 [--------]
+
+*** push past the hard block limit (expect EDQUOT)
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] =OK= 200 1000 0 [7 days] 10 4 10 00 [7 days] 0 0 0 00 [--------]
+
+*** unmount
+*** group
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data     = bsize=XXX blocks=XXX, imaxpct=PCT
+         = sunit=XXX swidth=XXX, unwritten=X
+naming   =VERN bsize=XXX
+log      =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+
+*** report no quota settings
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+
+*** report initial settings
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 0 200 1000 00 [--------] 1 4 10 00 [--------] 0 0 0 00 [--------]
+
+*** push past the soft inode limit
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 0 200 1000 00 [--------] 5 4 10 00 [7 days] 0 0 0 00 [--------]
+
+*** push past the soft block limit
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 300 200 1000 00 [7 days] 6 4 10 00 [7 days] 0 0 0 00 [--------]
+
+*** push past the hard inode limit (expect EDQUOT)
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 300 200 1000 00 [7 days] 10 4 10 00 [7 days] 0 0 0 00 [--------]
+
+*** push past the hard block limit (expect EDQUOT)
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] =OK= 200 1000 0 [7 days] 10 4 10 00 [7 days] 0 0 0 00 [--------]
+
+*** unmount
+*** uqnoenforce
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data     = bsize=XXX blocks=XXX, imaxpct=PCT
+         = sunit=XXX swidth=XXX, unwritten=X
+naming   =VERN bsize=XXX
+log      =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+
+*** report no quota settings
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+
+*** report initial settings
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 0 200 1000 00 [--------] 1 4 10 00 [--------] 0 0 0 00 [--------]
+
+*** push past the soft inode limit
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 0 200 1000 00 [--------] 5 4 10 00 [--------] 0 0 0 00 [--------]
+
+*** push past the soft block limit
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 300 200 1000 00 [--------] 6 4 10 00 [--------] 0 0 0 00 [--------]
+
+*** push past the hard inode limit (expect EDQUOT)
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 300 200 1000 00 [--------] 18 4 10 00 [--none--] 0 0 0 00 [--------]
+
+*** push past the hard block limit (expect EDQUOT)
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 1200 200 1000 00 [--none--] 18 4 10 00 [--none--] 0 0 0 00 [--------]
+
+*** unmount
+*** gqnoenforce
+meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks
+data     = bsize=XXX blocks=XXX, imaxpct=PCT
+         = sunit=XXX swidth=XXX, unwritten=X
+naming   =VERN bsize=XXX
+log      =LDEV bsize=XXX blocks=XXX
+realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX
+
+*** report no quota settings
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+
+*** report initial settings
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 0 200 1000 00 [--------] 1 4 10 00 [--------] 0 0 0 00 [--------]
+
+*** push past the soft inode limit
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 0 200 1000 00 [--------] 5 4 10 00 [--------] 0 0 0 00 [--------]
+
+*** push past the soft block limit
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 300 200 1000 00 [--------] 6 4 10 00 [--------] 0 0 0 00 [--------]
+
+*** push past the hard inode limit (expect EDQUOT)
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 300 200 1000 00 [--------] 18 4 10 00 [--none--] 0 0 0 00 [--------]
+
+*** push past the hard block limit (expect EDQUOT)
+[ROOT] 0 0 0 00 [--------] 3 0 0 00 [--------] 0 0 0 00 [--------]
+[NAME] 1200 200 1000 00 [--none--] 18 4 10 00 [--none--] 0 0 0 00 [--------]
+
+*** unmount
diff --git a/tests/xfs/group b/tests/xfs/group
index 03b447c7..0b4d1b21 100644
--- a/tests/xfs/group
+++ b/tests/xfs/group
@@ -506,3 +506,4 @@
 527 auto quick quota
 528 auto quick rw realtime
 529 auto quick quota idmapped
+530 auto quick quota idmapped
-- 
2.27.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
       [not found] ` <20210328223400.1800301-3-brauner@kernel.org>
@ 2021-04-11 14:30   ` Eryu Guan
  2021-04-11 15:12     ` Christian Brauner
  0 siblings, 1 reply; 24+ messages in thread
From: Eryu Guan @ 2021-04-11 14:30 UTC (permalink / raw)
  To: Christian Brauner
  Cc: fstests, Christoph Hellwig, Darrick J . Wong, David Howells,
	Christian Brauner, Amir Goldstein

On Mon, Mar 29, 2021 at 12:33:56AM +0200, Christian Brauner wrote:
> From: Christian Brauner <christian.brauner@ubuntu.com>
> 
> Add a test suite to verify the behavior of idmapped mounts. The test
> suite also includes a range of vfs tests to verify that no regressions
> are introduced by idmapped mounts. The following tests are currently
> available with more to come in the future:
> 
> 01. posix acls on regular and idmapped mounts

I'm getting failures like below when testing on btrfs and overlayfs

[root@fedoravm xfstests]# diff -u
/root/workspace/xfstests/tests/generic/633.out /root/workspace/xfstests/results//btrfs/generic/633.out.bad
--- /root/workspace/xfstests/tests/generic/633.out      2021-04-11 22:18: 24.458518716 +0800
+++ /root/workspace/xfstests/results//btrfs/generic/633.out.bad 2021-04-11 22:19:58.887980770 +0800
@@ -1,2 +1,4 @@
 QA output created by 633
  Silence is golden
  +idmapped-mounts.c: 6622: acls - Invalid argument - failure: sys_mount_setattr
  +failure: posix acls on regular mounts

Is this a known issue or test needs some fix?

[snip]

>  create mode 100644 tests/generic/632

Please change mode of new test file to 755 if you end up with sending
new version, otherwise I can fix it on commit.

Thanks,
Eryu

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 0/6] fstests: add idmapped mounts tests
  2021-03-28 22:33 [PATCH v12 0/6] fstests: add idmapped mounts tests Christian Brauner
                   ` (5 preceding siblings ...)
       [not found] ` <20210328223400.1800301-3-brauner@kernel.org>
@ 2021-04-11 14:37 ` Eryu Guan
  6 siblings, 0 replies; 24+ messages in thread
From: Eryu Guan @ 2021-04-11 14:37 UTC (permalink / raw)
  To: Christian Brauner
  Cc: fstests, Christoph Hellwig, Darrick J . Wong, David Howells,
	Christian Brauner

On Mon, Mar 29, 2021 at 12:33:54AM +0200, Christian Brauner wrote:
> From: Christian Brauner <christian.brauner@ubuntu.com>
> 
> Hey everyone,
> 
> This series is available from:
> https://git.kernel.org/brauner/xfstests-dev/h/idmapped_mounts
> https://gitlab.com/brauner/xfstests/-/tree/idmapped_mounts
> https://github.com/brauner/xfstests/tree/idmapped_mounts
> 
> /* v12 */
> - Main change is a fix to the io_uring tests. io_uring_wait_cqe()
>   doesn't set errno, it returns a negative errno.
> - Make sure we also run without error when libcap isn't available (That
>   was always the goal but the logic missed a few new tests.)

Thanks for the revision! The whole patchset looks fine to me, except
that I'm not sure if the generic/632 failure on btrfs & overlayfs is
expected.

With that resolved (either it's expected failure or test needs fix), I
think the patchset is ready to be merged.

Thanks,
Eryu

> 
> /* v11 */
> Reworked according to Amir's comments.
> 
> /* v10 */
> Reworked according to Eryu's comments.
> 
> /* v9 */
> Rebased onto current master.
> 
> ubuntu@f1-vm:~/src/git/xfstests$ sudo ./check -g idmapped
> FSTYP         -- xfs (debug)
> PLATFORM      -- Linux/x86_64 f1-vm 5.12.0-rc3-syz #18 SMP PREEMPT Fri Mar 26 13:27:16 UTC 2021
> MKFS_OPTIONS  -- -f -bsize=4096 /dev/loop1
> MOUNT_OPTIONS -- /dev/loop1 /mnt/scratch
> 
> generic/632 files ...  27s
> xfs/529 files ...  67s
> xfs/530 files ...  43s
> Ran: generic/632 xfs/529 xfs/530
> Passed all 3 tests
> 
> Thanks!
> Christian
> 
> Christian Brauner (6):
>   generic/631: add test for detached mount propagation
>   generic/632: add fstests for idmapped mounts
>   common/rc: add _scratch_{u}mount_idmapped() helpers
>   common/quota: move _qsetup() helper to common code
>   xfs/529: quotas and idmapped mounts
>   xfs/530: quotas on idmapped mounts
> 
>  .gitignore                            |    3 +
>  README                                |    5 +-
>  common/quota                          |   20 +
>  common/rc                             |   60 +
>  configure.ac                          |    2 +
>  include/builddefs.in                  |    1 +
>  m4/Makefile                           |    1 +
>  m4/package_libcap.m4                  |    4 +
>  src/Makefile                          |    8 +-
>  src/detached_mounts_propagation.c     |  189 +
>  src/feature.c                         |   40 +-
>  src/idmapped-mounts/Makefile          |   40 +
>  src/idmapped-mounts/idmapped-mounts.c | 8873 +++++++++++++++++++++++++
>  src/idmapped-mounts/missing.h         |  151 +
>  src/idmapped-mounts/mount-idmapped.c  |  431 ++
>  src/idmapped-mounts/utils.c           |  134 +
>  src/idmapped-mounts/utils.h           |   30 +
>  tests/generic/631                     |   43 +
>  tests/generic/631.out                 |    2 +
>  tests/generic/632                     |   42 +
>  tests/generic/632.out                 |    2 +
>  tests/generic/group                   |    2 +
>  tests/xfs/050                         |   19 -
>  tests/xfs/299                         |   19 -
>  tests/xfs/529                         |  377 ++
>  tests/xfs/529.out                     |  657 ++
>  tests/xfs/530                         |  212 +
>  tests/xfs/530.out                     |  129 +
>  tests/xfs/group                       |    2 +
>  29 files changed, 11453 insertions(+), 45 deletions(-)
>  create mode 100644 m4/package_libcap.m4
>  create mode 100644 src/detached_mounts_propagation.c
>  create mode 100644 src/idmapped-mounts/Makefile
>  create mode 100644 src/idmapped-mounts/idmapped-mounts.c
>  create mode 100644 src/idmapped-mounts/missing.h
>  create mode 100644 src/idmapped-mounts/mount-idmapped.c
>  create mode 100644 src/idmapped-mounts/utils.c
>  create mode 100644 src/idmapped-mounts/utils.h
>  create mode 100644 tests/generic/631
>  create mode 100644 tests/generic/631.out
>  create mode 100644 tests/generic/632
>  create mode 100644 tests/generic/632.out
>  create mode 100644 tests/xfs/529
>  create mode 100644 tests/xfs/529.out
>  create mode 100644 tests/xfs/530
>  create mode 100644 tests/xfs/530.out
> 
> 
> base-commit: f6ddaf130d5b0817278afe441fdde52f464f321b
> -- 
> 2.27.0

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-11 14:30   ` [PATCH v12 2/6] generic/632: add fstests for " Eryu Guan
@ 2021-04-11 15:12     ` Christian Brauner
  2021-04-11 15:18       ` Christian Brauner
  2021-04-11 15:19       ` Eryu Guan
  0 siblings, 2 replies; 24+ messages in thread
From: Christian Brauner @ 2021-04-11 15:12 UTC (permalink / raw)
  To: Eryu Guan
  Cc: Christian Brauner, fstests, Christoph Hellwig, Darrick J . Wong,
	David Howells, Amir Goldstein

On Sun, Apr 11, 2021 at 10:30:20PM +0800, Eryu Guan wrote:
> On Mon, Mar 29, 2021 at 12:33:56AM +0200, Christian Brauner wrote:
> > From: Christian Brauner <christian.brauner@ubuntu.com>
> > 
> > Add a test suite to verify the behavior of idmapped mounts. The test
> > suite also includes a range of vfs tests to verify that no regressions
> > are introduced by idmapped mounts. The following tests are currently
> > available with more to come in the future:
> > 
> > 01. posix acls on regular and idmapped mounts
> 
> I'm getting failures like below when testing on btrfs and overlayfs
> 
> [root@fedoravm xfstests]# diff -u
> /root/workspace/xfstests/tests/generic/633.out /root/workspace/xfstests/results//btrfs/generic/633.out.bad
> --- /root/workspace/xfstests/tests/generic/633.out      2021-04-11 22:18: 24.458518716 +0800
> +++ /root/workspace/xfstests/results//btrfs/generic/633.out.bad 2021-04-11 22:19:58.887980770 +0800
> @@ -1,2 +1,4 @@
>  QA output created by 633
>   Silence is golden
>   +idmapped-mounts.c: 6622: acls - Invalid argument - failure: sys_mount_setattr
>   +failure: posix acls on regular mounts
> 
> Is this a known issue or test needs some fix?

Ah, this is very likely just the getfacl command missing which is part
of the "acl" package, at least on Ubuntu.

Christian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-11 15:12     ` Christian Brauner
@ 2021-04-11 15:18       ` Christian Brauner
  2021-04-11 15:21         ` Eryu Guan
  2021-04-11 15:19       ` Eryu Guan
  1 sibling, 1 reply; 24+ messages in thread
From: Christian Brauner @ 2021-04-11 15:18 UTC (permalink / raw)
  To: Eryu Guan
  Cc: Christian Brauner, fstests, Christoph Hellwig, Darrick J . Wong,
	David Howells, Amir Goldstein

On Sun, Apr 11, 2021 at 05:12:49PM +0200, Christian Brauner wrote:
> On Sun, Apr 11, 2021 at 10:30:20PM +0800, Eryu Guan wrote:
> > On Mon, Mar 29, 2021 at 12:33:56AM +0200, Christian Brauner wrote:
> > > From: Christian Brauner <christian.brauner@ubuntu.com>
> > > 
> > > Add a test suite to verify the behavior of idmapped mounts. The test
> > > suite also includes a range of vfs tests to verify that no regressions
> > > are introduced by idmapped mounts. The following tests are currently
> > > available with more to come in the future:
> > > 
> > > 01. posix acls on regular and idmapped mounts
> > 
> > I'm getting failures like below when testing on btrfs and overlayfs
> > 
> > [root@fedoravm xfstests]# diff -u
> > /root/workspace/xfstests/tests/generic/633.out /root/workspace/xfstests/results//btrfs/generic/633.out.bad
> > --- /root/workspace/xfstests/tests/generic/633.out      2021-04-11 22:18: 24.458518716 +0800
> > +++ /root/workspace/xfstests/results//btrfs/generic/633.out.bad 2021-04-11 22:19:58.887980770 +0800
> > @@ -1,2 +1,4 @@
> >  QA output created by 633
> >   Silence is golden
> >   +idmapped-mounts.c: 6622: acls - Invalid argument - failure: sys_mount_setattr
> >   +failure: posix acls on regular mounts
> > 
> > Is this a known issue or test needs some fix?
> 
> Ah, this is very likely just the getfacl command missing which is part
> of the "acl" package, at least on Ubuntu.

And it should actually skip the tests on all filesystems that don't
support idmapped mounts which is every fs apart from xfs and ext4.

Christian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-11 15:12     ` Christian Brauner
  2021-04-11 15:18       ` Christian Brauner
@ 2021-04-11 15:19       ` Eryu Guan
  1 sibling, 0 replies; 24+ messages in thread
From: Eryu Guan @ 2021-04-11 15:19 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Christian Brauner, fstests, Christoph Hellwig, Darrick J . Wong,
	David Howells, Amir Goldstein

On Sun, Apr 11, 2021 at 05:12:49PM +0200, Christian Brauner wrote:
> On Sun, Apr 11, 2021 at 10:30:20PM +0800, Eryu Guan wrote:
> > On Mon, Mar 29, 2021 at 12:33:56AM +0200, Christian Brauner wrote:
> > > From: Christian Brauner <christian.brauner@ubuntu.com>
> > > 
> > > Add a test suite to verify the behavior of idmapped mounts. The test
> > > suite also includes a range of vfs tests to verify that no regressions
> > > are introduced by idmapped mounts. The following tests are currently
> > > available with more to come in the future:
> > > 
> > > 01. posix acls on regular and idmapped mounts
> > 
> > I'm getting failures like below when testing on btrfs and overlayfs
> > 
> > [root@fedoravm xfstests]# diff -u
> > /root/workspace/xfstests/tests/generic/633.out /root/workspace/xfstests/results//btrfs/generic/633.out.bad
> > --- /root/workspace/xfstests/tests/generic/633.out      2021-04-11 22:18: 24.458518716 +0800
> > +++ /root/workspace/xfstests/results//btrfs/generic/633.out.bad 2021-04-11 22:19:58.887980770 +0800
> > @@ -1,2 +1,4 @@
> >  QA output created by 633
> >   Silence is golden
> >   +idmapped-mounts.c: 6622: acls - Invalid argument - failure: sys_mount_setattr
> >   +failure: posix acls on regular mounts
> > 
> > Is this a known issue or test needs some fix?
> 
> Ah, this is very likely just the getfacl command missing which is part
> of the "acl" package, at least on Ubuntu.

I do have getfacl command installed, and test passed if I tested on ext4
or xfs. So I don't think it's related to getfacl command.

Thanks,
Eryu

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-11 15:18       ` Christian Brauner
@ 2021-04-11 15:21         ` Eryu Guan
  2021-04-11 15:32           ` Christian Brauner
  0 siblings, 1 reply; 24+ messages in thread
From: Eryu Guan @ 2021-04-11 15:21 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Christian Brauner, fstests, Christoph Hellwig, Darrick J . Wong,
	David Howells, Amir Goldstein

On Sun, Apr 11, 2021 at 05:18:57PM +0200, Christian Brauner wrote:
> On Sun, Apr 11, 2021 at 05:12:49PM +0200, Christian Brauner wrote:
> > On Sun, Apr 11, 2021 at 10:30:20PM +0800, Eryu Guan wrote:
> > > On Mon, Mar 29, 2021 at 12:33:56AM +0200, Christian Brauner wrote:
> > > > From: Christian Brauner <christian.brauner@ubuntu.com>
> > > > 
> > > > Add a test suite to verify the behavior of idmapped mounts. The test
> > > > suite also includes a range of vfs tests to verify that no regressions
> > > > are introduced by idmapped mounts. The following tests are currently
> > > > available with more to come in the future:
> > > > 
> > > > 01. posix acls on regular and idmapped mounts
> > > 
> > > I'm getting failures like below when testing on btrfs and overlayfs
> > > 
> > > [root@fedoravm xfstests]# diff -u
> > > /root/workspace/xfstests/tests/generic/633.out /root/workspace/xfstests/results//btrfs/generic/633.out.bad
> > > --- /root/workspace/xfstests/tests/generic/633.out      2021-04-11 22:18: 24.458518716 +0800
> > > +++ /root/workspace/xfstests/results//btrfs/generic/633.out.bad 2021-04-11 22:19:58.887980770 +0800
> > > @@ -1,2 +1,4 @@
> > >  QA output created by 633
> > >   Silence is golden
> > >   +idmapped-mounts.c: 6622: acls - Invalid argument - failure: sys_mount_setattr
> > >   +failure: posix acls on regular mounts
> > > 
> > > Is this a known issue or test needs some fix?
> > 
> > Ah, this is very likely just the getfacl command missing which is part
> > of the "acl" package, at least on Ubuntu.
> 
> And it should actually skip the tests on all filesystems that don't
> support idmapped mounts which is every fs apart from xfs and ext4.

Yeah, looks like that's the case. So it seems the _require idmapped
mount helper doesn't do the job properly.

Eryu

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-11 15:21         ` Eryu Guan
@ 2021-04-11 15:32           ` Christian Brauner
  2021-04-12  0:40             ` Theodore Ts'o
  2021-04-12  7:22             ` [PATCH v12 2/6] generic/632: add fstests for " Christoph Hellwig
  0 siblings, 2 replies; 24+ messages in thread
From: Christian Brauner @ 2021-04-11 15:32 UTC (permalink / raw)
  To: Eryu Guan
  Cc: Christian Brauner, fstests, Christoph Hellwig, Darrick J . Wong,
	David Howells, Amir Goldstein

On Sun, Apr 11, 2021 at 11:21:36PM +0800, Eryu Guan wrote:
> On Sun, Apr 11, 2021 at 05:18:57PM +0200, Christian Brauner wrote:
> > On Sun, Apr 11, 2021 at 05:12:49PM +0200, Christian Brauner wrote:
> > > On Sun, Apr 11, 2021 at 10:30:20PM +0800, Eryu Guan wrote:
> > > > On Mon, Mar 29, 2021 at 12:33:56AM +0200, Christian Brauner wrote:
> > > > > From: Christian Brauner <christian.brauner@ubuntu.com>
> > > > > 
> > > > > Add a test suite to verify the behavior of idmapped mounts. The test
> > > > > suite also includes a range of vfs tests to verify that no regressions
> > > > > are introduced by idmapped mounts. The following tests are currently
> > > > > available with more to come in the future:
> > > > > 
> > > > > 01. posix acls on regular and idmapped mounts
> > > > 
> > > > I'm getting failures like below when testing on btrfs and overlayfs
> > > > 
> > > > [root@fedoravm xfstests]# diff -u
> > > > /root/workspace/xfstests/tests/generic/633.out /root/workspace/xfstests/results//btrfs/generic/633.out.bad
> > > > --- /root/workspace/xfstests/tests/generic/633.out      2021-04-11 22:18: 24.458518716 +0800
> > > > +++ /root/workspace/xfstests/results//btrfs/generic/633.out.bad 2021-04-11 22:19:58.887980770 +0800
> > > > @@ -1,2 +1,4 @@
> > > >  QA output created by 633
> > > >   Silence is golden
> > > >   +idmapped-mounts.c: 6622: acls - Invalid argument - failure: sys_mount_setattr
> > > >   +failure: posix acls on regular mounts
> > > > 
> > > > Is this a known issue or test needs some fix?
> > > 
> > > Ah, this is very likely just the getfacl command missing which is part
> > > of the "acl" package, at least on Ubuntu.
> > 
> > And it should actually skip the tests on all filesystems that don't
> > support idmapped mounts which is every fs apart from xfs and ext4.
> 
> Yeah, looks like that's the case. So it seems the _require idmapped

Ah, ok I didn't know this needed to go in there. I thinke the following
might be enough. Are you able to simply apply it on top?

diff --git a/common/rc b/common/rc
index 351996fc..bd913d13 100644
--- a/common/rc
+++ b/common/rc
@@ -2047,6 +2047,16 @@ _require_mount_setattr()
 # test whether idmapped mounts are supported
 _require_idmapped_mounts()
 {
+       case "$FSTYP" in
+       xfs)
+               ;;
+       ext4)
+               ;;
+       *)
+               _notrun "Filesystem $FSTYP does not support idmapped mounts yet"
+               ;;
+       esac
+
         IDMAPPED_MOUNTS_TEST=$here/src/idmapped-mounts/idmapped-mounts
         [ -x $IDMAPPED_MOUNTS_TEST ] || _notrun "idmapped-mounts utilities required"

Christian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-11 15:32           ` Christian Brauner
@ 2021-04-12  0:40             ` Theodore Ts'o
  2021-04-12 11:54               ` Christian Brauner
  2021-04-12  7:22             ` [PATCH v12 2/6] generic/632: add fstests for " Christoph Hellwig
  1 sibling, 1 reply; 24+ messages in thread
From: Theodore Ts'o @ 2021-04-12  0:40 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Eryu Guan, Christian Brauner, fstests, Christoph Hellwig,
	Darrick J . Wong, David Howells, Amir Goldstein

On Sun, Apr 11, 2021 at 05:32:23PM +0200, Christian Brauner wrote:
> Ah, ok I didn't know this needed to go in there. I thinke the following
> might be enough. Are you able to simply apply it on top?
> 
> diff --git a/common/rc b/common/rc
> index 351996fc..bd913d13 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -2047,6 +2047,16 @@ _require_mount_setattr()
>  # test whether idmapped mounts are supported
>  _require_idmapped_mounts()
>  {
> +       case "$FSTYP" in
> +       xfs)
> +               ;;
> +       ext4)
> +               ;;
> +       *)
> +               _notrun "Filesystem $FSTYP does not support idmapped mounts yet"
> +               ;;
> +       esac
> +

Is there any way we can ask the kernel which file systems support
idmapped mounts?  That way, the tests will do the right thing when run
on older LTS kernels, and if a distribution backports idmapped support
for some file system into their kernel, again, the right thing can
happen automatically.

If you can't do this by checking to see if the file system will
support a particular mount option, or some other run-time test, for
ext4 we can signal this by checking for the existence of a file in
/sys/fs/ext4/features, such as /sys/fs/ext4/features/fast_commit.
(Grep for EXT4_ATTR_FEATURE and ATTR_LIST in fs/ext4/sysfs.c; it
requires adding two lines to advertise a new ext4 feature.)

	 	    	     	       - Ted

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-11 15:32           ` Christian Brauner
  2021-04-12  0:40             ` Theodore Ts'o
@ 2021-04-12  7:22             ` Christoph Hellwig
  2021-04-12  7:30               ` Christian Brauner
  1 sibling, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2021-04-12  7:22 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Eryu Guan, Christian Brauner, fstests, Christoph Hellwig,
	Darrick J . Wong, David Howells, Amir Goldstein

On Sun, Apr 11, 2021 at 05:32:23PM +0200, Christian Brauner wrote:
> > > And it should actually skip the tests on all filesystems that don't
> > > support idmapped mounts which is every fs apart from xfs and ext4.
> > 
> > Yeah, looks like that's the case. So it seems the _require idmapped
> 
> Ah, ok I didn't know this needed to go in there. I thinke the following
> might be enough. Are you able to simply apply it on top?

No, this is broken.  It needs to do feature detection, not some arbitrary
whitelists.  And I'm pretty sure we got that right at some point by
doing the _notrun when mounting with the idmap option was not supported.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-12  7:22             ` [PATCH v12 2/6] generic/632: add fstests for " Christoph Hellwig
@ 2021-04-12  7:30               ` Christian Brauner
  0 siblings, 0 replies; 24+ messages in thread
From: Christian Brauner @ 2021-04-12  7:30 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Eryu Guan, Christian Brauner, fstests, Darrick J . Wong,
	David Howells, Amir Goldstein

On Mon, Apr 12, 2021 at 09:22:41AM +0200, Christoph Hellwig wrote:
> On Sun, Apr 11, 2021 at 05:32:23PM +0200, Christian Brauner wrote:
> > > > And it should actually skip the tests on all filesystems that don't
> > > > support idmapped mounts which is every fs apart from xfs and ext4.
> > > 
> > > Yeah, looks like that's the case. So it seems the _require idmapped
> > 
> > Ah, ok I didn't know this needed to go in there. I thinke the following
> > might be enough. Are you able to simply apply it on top?
> 
> No, this is broken.  It needs to do feature detection, not some arbitrary
> whitelists.  And I'm pretty sure we got that right at some point by

I thought so too.

> doing the _notrun when mounting with the idmap option was not supported.

The thing is we need the fileystem type we're going to be tested on. I
can place this into src/feature.c if this can get access to the fstype
the test is going to be run on. It should be but if not we can do this
in src/idmapped-mounts/idmapped-mounts.c
directly to test whether the underlying fs we're being tested on
supports idmapped mounts and then return an error value from the binary
indicating that it doesn't so we can use _notrun.
I'll post an updated version of this today with the detection logic.

Christian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-12  0:40             ` Theodore Ts'o
@ 2021-04-12 11:54               ` Christian Brauner
  2021-04-12 22:41                 ` Theodore Ts'o
  0 siblings, 1 reply; 24+ messages in thread
From: Christian Brauner @ 2021-04-12 11:54 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Eryu Guan, Christian Brauner, fstests, Christoph Hellwig,
	Darrick J . Wong, David Howells, Amir Goldstein

On Sun, Apr 11, 2021 at 08:40:12PM -0400, Theodore Ts'o wrote:
> On Sun, Apr 11, 2021 at 05:32:23PM +0200, Christian Brauner wrote:
> > Ah, ok I didn't know this needed to go in there. I thinke the following
> > might be enough. Are you able to simply apply it on top?
> > 
> > diff --git a/common/rc b/common/rc
> > index 351996fc..bd913d13 100644
> > --- a/common/rc
> > +++ b/common/rc
> > @@ -2047,6 +2047,16 @@ _require_mount_setattr()
> >  # test whether idmapped mounts are supported
> >  _require_idmapped_mounts()
> >  {
> > +       case "$FSTYP" in
> > +       xfs)
> > +               ;;
> > +       ext4)
> > +               ;;
> > +       *)
> > +               _notrun "Filesystem $FSTYP does not support idmapped mounts yet"
> > +               ;;
> > +       esac
> > +
> 
> Is there any way we can ask the kernel which file systems support
> idmapped mounts?  That way, the tests will do the right thing when run
> on older LTS kernels, and if a distribution backports idmapped support
> for some file system into their kernel, again, the right thing can
> happen automatically.

So we can detect it pretty reliably at runtime by trying whether we can
create an idmapped mount on the given filesystem. That is enough for the
idmapped mount tests here but of course has at least two drawbacks:
1. there might be scenarios where we get false negatives
   (e.g. open_tree() could fail for a lack of permissions or sm else,
   kernel might be compiled without userns support etc. pp)
2. it's heavy in so far as we have to do the whole exercise of creating
   a detached mount
So having a reliable way to detect whether or not the underlying fs
supports it could be worth it (My hope was for the fsinfo() API to grow
this "feature check" ability but oh well.).

One possibility might be to extend fstatfs() and steal one u32 from the
padding that is currently in there?

> 
> If you can't do this by checking to see if the file system will
> support a particular mount option, or some other run-time test, for
> ext4 we can signal this by checking for the existence of a file in
> /sys/fs/ext4/features, such as /sys/fs/ext4/features/fast_commit.
> (Grep for EXT4_ATTR_FEATURE and ATTR_LIST in fs/ext4/sysfs.c; it
> requires adding two lines to advertise a new ext4 feature.)

I wonder if this wouldn't be nice to have independent of whether or not
there is another way to detect it?
I'm would think that people like to see all new ext4 features listed in
there. Even if this is technically a generic vfs feature.

Christian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v12 2/6] generic/632: add fstests for idmapped mounts
  2021-04-12 11:54               ` Christian Brauner
@ 2021-04-12 22:41                 ` Theodore Ts'o
  2021-04-14 20:47                   ` [PATCH -RFC] ext4: add feature file to advertise that ext4 supports " Theodore Ts'o
  0 siblings, 1 reply; 24+ messages in thread
From: Theodore Ts'o @ 2021-04-12 22:41 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Eryu Guan, Christian Brauner, fstests, Christoph Hellwig,
	Darrick J . Wong, David Howells, Amir Goldstein

On Mon, Apr 12, 2021 at 01:54:26PM +0200, Christian Brauner wrote:
>So we can detect it pretty reliably at runtime by trying whether we can
>create an idmapped mount on the given filesystem. That is enough for the
>idmapped mount tests here but of course has at least two drawbacks:
>1. there might be scenarios where we get false negatives
>   (e.g. open_tree() could fail for a lack of permissions or sm else,
>   kernel might be compiled without userns support etc. pp)

In the ideal world, if the kernel wasn't compiled with the necessary
CONFIG options enabled, it's desirable of the test can detect that
fact and skip running the test instead failing and forcing the person
running the test to try to figure out whether this is a legitmate file
system bug or a just a test setup bug.

This is one of the other functions of /sys/fs/ext4/features/...  for
example:

#ifdef CONFIG_UNICODE
EXT4_ATTR_FEATURE(casefold);
#endif

That way, if a particular kernel CONFIG is not compiled in, we can
prevent the feature from being advertised, without having to rely on
/proc/config.gz be present.

>2. it's heavy in so far as we have to do the whole exercise of creating
>   a detached mount

Yeah, there are times when I've added a new feature flag file in
/sys/fs/ext4/features because it was simpler than being able to doing
some kind of heavyweight test.

> So having a reliable way to detect whether or not the underlying fs
> supports it could be worth it (My hope was for the fsinfo() API to grow
> this "feature check" ability but oh well.).
> 
> One possibility might be to extend fstatfs() and steal one u32 from the
> padding that is currently in there?

That would require mounting a file system in order to do the check,
which is not necesarily always convenient, but that would certainly
work.  (See below for an example of where it was much easier for
mke2fs to be able to test for a file system "capability" without
needing to mount a test file system.)

> > If you can't do this by checking to see if the file system will
> > support a particular mount option, or some other run-time test, for
> > ext4 we can signal this by checking for the existence of a file in
> > /sys/fs/ext4/features, such as /sys/fs/ext4/features/fast_commit.
> > (Grep for EXT4_ATTR_FEATURE and ATTR_LIST in fs/ext4/sysfs.c; it
> > requires adding two lines to advertise a new ext4 feature.)
> 
> I wonder if this wouldn't be nice to have independent of whether or not
> there is another way to detect it?
> I'm would think that people like to see all new ext4 features listed in
> there. Even if this is technically a generic vfs feature.

My apologies for the confusion.  There's a bit of overloading in terms
of the word "features" as used above.  In some cases, there is a
direct correspondance between bits that show up in the compat,
ro_compat, and incompat fields in the ext4 superblock.  In other cases
it might describe a file system behaviour (e.g., lazy_itable_init) and
this acts as a hint to e2fsprogs about what kind of defaults it should
use when creating a file system --- or to warn the user about whether
a particular file system can be mounted using the current kernel.

For example, currently we give the following warning if you create a
file system with a 64k block size:

% mke2fs -t ext4 -b 65536 /tmp/foo.img 8M
Warning: blocksize 65536 not usable on most systems.
mke2fs 1.46.2 (28-Feb-2021)
Creating regular file /tmp/foo.img
mke2fs: 65536-byte blocks too big for system (max 4096)
Proceed anyway? (y,N)

However, suppose at some point, thanks to advances in the MM layer, it
becomes possible to support file systems where the block size is
greater than the page size.  We might then advertise that via the
existing of a file such as /sys/fs/ext4/feature/big_blocks (for
example), and then newer versions of mke2fs would check for that file
and suppress the warning on a kernel which would actually allow file
systems with 64k blocks to be mounted on an x86_64 system.  This is
also why I designed it via using a file in /sys/fs/ext4/features, so
that I don't have to do a test mount and use a system call fstatfs(2)
to check for the existenace of an ext4 feature/capability (all of the
obvious terms are already overloaded, sigh).

I agree that having some kind of fs-independent way for querying
whether some feature/capability is present for a particular kernel
would be convenient.  This wouldn't necessarily need to be implemented
in the VFS, though, especially if the convention that gets adopted is
via a file in /sys/fs/<fstype>/features/<capability>.

						- Ted

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH -RFC] ext4: add feature file to advertise that ext4 supports idmapped mounts
  2021-04-12 22:41                 ` Theodore Ts'o
@ 2021-04-14 20:47                   ` Theodore Ts'o
  2021-04-15  5:54                     ` Christoph Hellwig
  0 siblings, 1 reply; 24+ messages in thread
From: Theodore Ts'o @ 2021-04-14 20:47 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Eryu Guan, Christian Brauner, fstests, Christoph Hellwig,
	linux-ext4, Darrick J . Wong, David Howells, Amir Goldstein

On Mon, Apr 12, 2021 at 06:41:20PM -0400, Theodore Ts'o wrote:
> In the ideal world, if the kernel wasn't compiled with the necessary
> CONFIG options enabled, it's desirable of the test can detect that
> fact and skip running the test instead failing and forcing the person
> running the test to try to figure out whether this is a legitmate file
> system bug or a just a test setup bug.

So it would make it easier for me to manage running xfstests on ext4
if I had added something like this to ext4 and sent it to Linus before
v5.12 is released.  What do folks think?

							- Ted


commit 20619aefe69d39e76083d8f8598653c2dca9b47e
Author: Theodore Ts'o <tytso@mit.edu>
Date:   Wed Apr 14 16:42:47 2021 -0400

    ext4: add feature file to advertise that ext4 supports idmapped mounts
    
    This makes it easier for automated test suites to know whether it know
    whether we should test the functionality of the new idmapped mounts
    feature introduced in v5.12-rc1.
    
    Signed-off-by: Theodore Ts'o <tytso@mit.edu>

diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
index a3d08276d441..101bf700c16b 100644
--- a/fs/ext4/sysfs.c
+++ b/fs/ext4/sysfs.c
@@ -313,6 +313,9 @@ EXT4_ATTR_FEATURE(verity);
 #endif
 EXT4_ATTR_FEATURE(metadata_csum_seed);
 EXT4_ATTR_FEATURE(fast_commit);
+#ifdef CONFIG_USER_NS
+EXT4_ATTR_FEATURE(idmapped_mount);
+#endif
 
 static struct attribute *ext4_feat_attrs[] = {
 	ATTR_LIST(lazy_itable_init),
@@ -330,6 +333,9 @@ static struct attribute *ext4_feat_attrs[] = {
 #endif
 	ATTR_LIST(metadata_csum_seed),
 	ATTR_LIST(fast_commit),
+#ifdef CONFIG_USER_NS
+	ATTR_LIST(idmapped_mount),
+#endif
 	NULL,
 };
 ATTRIBUTE_GROUPS(ext4_feat);

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH -RFC] ext4: add feature file to advertise that ext4 supports idmapped mounts
  2021-04-14 20:47                   ` [PATCH -RFC] ext4: add feature file to advertise that ext4 supports " Theodore Ts'o
@ 2021-04-15  5:54                     ` Christoph Hellwig
  2021-04-15  7:49                       ` Christian Brauner
  0 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2021-04-15  5:54 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Christian Brauner, Eryu Guan, Christian Brauner, fstests,
	Christoph Hellwig, linux-ext4, Darrick J . Wong, David Howells,
	Amir Goldstein

On Wed, Apr 14, 2021 at 04:47:10PM -0400, Theodore Ts'o wrote:
> On Mon, Apr 12, 2021 at 06:41:20PM -0400, Theodore Ts'o wrote:
> > In the ideal world, if the kernel wasn't compiled with the necessary
> > CONFIG options enabled, it's desirable of the test can detect that
> > fact and skip running the test instead failing and forcing the person
> > running the test to try to figure out whether this is a legitmate file
> > system bug or a just a test setup bug.
> 
> So it would make it easier for me to manage running xfstests on ext4
> if I had added something like this to ext4 and sent it to Linus before
> v5.12 is released.  What do folks think?

Completely stupid.  This is a VFS-level feature and we need to have
proper VFS-level testing (which we have through creating a mount
with the option), not fs-specific band aids.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH -RFC] ext4: add feature file to advertise that ext4 supports idmapped mounts
  2021-04-15  5:54                     ` Christoph Hellwig
@ 2021-04-15  7:49                       ` Christian Brauner
  2021-04-15  7:55                         ` Christoph Hellwig
  2021-04-15 14:59                         ` Theodore Ts'o
  0 siblings, 2 replies; 24+ messages in thread
From: Christian Brauner @ 2021-04-15  7:49 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Theodore Ts'o, Eryu Guan, Christian Brauner, fstests,
	linux-ext4, Darrick J . Wong, David Howells, Amir Goldstein

On Thu, Apr 15, 2021 at 07:54:08AM +0200, Christoph Hellwig wrote:
> On Wed, Apr 14, 2021 at 04:47:10PM -0400, Theodore Ts'o wrote:
> > On Mon, Apr 12, 2021 at 06:41:20PM -0400, Theodore Ts'o wrote:
> > > In the ideal world, if the kernel wasn't compiled with the necessary
> > > CONFIG options enabled, it's desirable of the test can detect that
> > > fact and skip running the test instead failing and forcing the person
> > > running the test to try to figure out whether this is a legitmate file
> > > system bug or a just a test setup bug.
> > 
> > So it would make it easier for me to manage running xfstests on ext4
> > if I had added something like this to ext4 and sent it to Linus before
> > v5.12 is released.  What do folks think?
> 
> Completely stupid.  This is a VFS-level feature and we need to have
> proper VFS-level testing (which we have through creating a mount
> with the option), not fs-specific band aids.

Harsh words. :)
Christoph's right though I think for the xfstests we don't need it and
we're covered with what we have in the version I sent out last Sunday.

However, as a general way of advertising to users that ext4 supports
idmapped mounts I don't necessarily see a problem with that. It doesn't
have implications for other filesystems and ext4 already advertises
other features in a similar way.

Christian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH -RFC] ext4: add feature file to advertise that ext4 supports idmapped mounts
  2021-04-15  7:49                       ` Christian Brauner
@ 2021-04-15  7:55                         ` Christoph Hellwig
  2021-04-15  8:13                           ` Christian Brauner
  2021-04-15 14:59                         ` Theodore Ts'o
  1 sibling, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2021-04-15  7:55 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Christoph Hellwig, Theodore Ts'o, Eryu Guan,
	Christian Brauner, fstests, linux-ext4, Darrick J . Wong,
	David Howells, Amir Goldstein

On Thu, Apr 15, 2021 at 09:49:21AM +0200, Christian Brauner wrote:
> However, as a general way of advertising to users that ext4 supports
> idmapped mounts I don't necessarily see a problem with that. It doesn't
> have implications for other filesystems and ext4 already advertises
> other features in a similar way.

I still think that is a very bad idea.  idmapped mounts are foremost
a VFS feature, with just a tiny bit of glue in every file system that
does not affect the on-disk format.  So any discovery for it needs
to be using VFS infrastructure.  IMHO just trying to mount is the
proper way to do it, but if people want some other form of discovery
it needs to be something in generic code.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH -RFC] ext4: add feature file to advertise that ext4 supports idmapped mounts
  2021-04-15  7:55                         ` Christoph Hellwig
@ 2021-04-15  8:13                           ` Christian Brauner
  0 siblings, 0 replies; 24+ messages in thread
From: Christian Brauner @ 2021-04-15  8:13 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Theodore Ts'o, Eryu Guan, Christian Brauner, fstests,
	linux-ext4, Darrick J . Wong, David Howells, Amir Goldstein

On Thu, Apr 15, 2021 at 09:55:37AM +0200, Christoph Hellwig wrote:
> On Thu, Apr 15, 2021 at 09:49:21AM +0200, Christian Brauner wrote:
> > However, as a general way of advertising to users that ext4 supports
> > idmapped mounts I don't necessarily see a problem with that. It doesn't
> > have implications for other filesystems and ext4 already advertises
> > other features in a similar way.
> 
> I still think that is a very bad idea.  idmapped mounts are foremost
> a VFS feature, with just a tiny bit of glue in every file system that
> does not affect the on-disk format.  So any discovery for it needs
> to be using VFS infrastructure.  IMHO just trying to mount is the
> proper way to do it, but if people want some other form of discovery
> it needs to be something in generic code.

I agree with you there.
I think fsinfo() (Arguably a slimmed-down version of it.) would've been
the best place for this.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH -RFC] ext4: add feature file to advertise that ext4 supports idmapped mounts
  2021-04-15  7:49                       ` Christian Brauner
  2021-04-15  7:55                         ` Christoph Hellwig
@ 2021-04-15 14:59                         ` Theodore Ts'o
  1 sibling, 0 replies; 24+ messages in thread
From: Theodore Ts'o @ 2021-04-15 14:59 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Christoph Hellwig, Eryu Guan, Christian Brauner, fstests,
	linux-ext4, Darrick J . Wong, David Howells, Amir Goldstein

On Thu, Apr 15, 2021 at 09:49:21AM +0200, Christian Brauner wrote:
> Harsh words. :)
> Christoph's right though I think for the xfstests we don't need it and
> we're covered with what we have in the version I sent out last Sunday.

Sorry, I had missed your v13 patch set and that it had included tests
for the existence of idmapped.  I had sent out the RFC patch because I
was under the impression that we hadn't made forward progress on
testing for the support idmapped mounts.

If we have a way of doing this, and you're comfortable that it is
reliable (e.g., that a bug might cause the test to be skipped because
it thinks the file system doesn't support idmapped mount, when really
it was caused by a regression), and I'm happy to just rely on the
method you've used in the v13 fstests patch set.

That being said, I still think it would be helpful to have a
VFS-standard way for userspace to be able to test for the presence of
a particular kernel feature/capability without having to do a test
mount, possibly requiring setting up a test user_ns, etc., etc.  But
that isn't as urgent as making sure we can easily the feature without
needing manual customization of the test suite as file systems add
support for the feature, or as the feature gets backported to
enterprise distro kernels.

Cheers,

					- Ted

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, back to index

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-28 22:33 [PATCH v12 0/6] fstests: add idmapped mounts tests Christian Brauner
2021-03-28 22:33 ` [PATCH v12 1/6] generic/631: add test for detached mount propagation Christian Brauner
2021-03-28 22:33 ` [PATCH v12 3/6] common/rc: add _scratch_{u}mount_idmapped() helpers Christian Brauner
2021-03-28 22:33 ` [PATCH v12 4/6] common/quota: move _qsetup() helper to common code Christian Brauner
2021-03-28 22:33 ` [PATCH v12 5/6] xfs/529: quotas and idmapped mounts Christian Brauner
2021-03-28 22:34 ` [PATCH v12 6/6] xfs/530: quotas on " Christian Brauner
     [not found] ` <20210328223400.1800301-3-brauner@kernel.org>
2021-04-11 14:30   ` [PATCH v12 2/6] generic/632: add fstests for " Eryu Guan
2021-04-11 15:12     ` Christian Brauner
2021-04-11 15:18       ` Christian Brauner
2021-04-11 15:21         ` Eryu Guan
2021-04-11 15:32           ` Christian Brauner
2021-04-12  0:40             ` Theodore Ts'o
2021-04-12 11:54               ` Christian Brauner
2021-04-12 22:41                 ` Theodore Ts'o
2021-04-14 20:47                   ` [PATCH -RFC] ext4: add feature file to advertise that ext4 supports " Theodore Ts'o
2021-04-15  5:54                     ` Christoph Hellwig
2021-04-15  7:49                       ` Christian Brauner
2021-04-15  7:55                         ` Christoph Hellwig
2021-04-15  8:13                           ` Christian Brauner
2021-04-15 14:59                         ` Theodore Ts'o
2021-04-12  7:22             ` [PATCH v12 2/6] generic/632: add fstests for " Christoph Hellwig
2021-04-12  7:30               ` Christian Brauner
2021-04-11 15:19       ` Eryu Guan
2021-04-11 14:37 ` [PATCH v12 0/6] fstests: add idmapped mounts tests Eryu Guan

FSTests Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/fstests/0 fstests/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 fstests fstests/ https://lore.kernel.org/fstests \
		fstests@vger.kernel.org
	public-inbox-index fstests

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.fstests


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git