public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCHSET] xfsprogs: filesystem properties
@ 2024-07-30  3:10 Darrick J. Wong
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
                   ` (4 more replies)
  0 siblings, 5 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:10 UTC (permalink / raw)
  To: Christoph Hellwig, Dave Chinner; +Cc: xfs

Hi all,

After last week's discussion about how to allow sysadmins to opt in or
out of autonomous self healing XFS[1], I now have an RFC patchset that
implements the filesystem properties that we talked about.

As a refresher, the design I settled on is to add ATTR_ROOT (aka
"trusted") xattrs to the root directory.  ATTR_ROOT xattrs can only be
accessed by processes with CAP_SYS_ADMIN, so unprivileged userspace
can't mess with the sysadmin's configured preferences.

I decided that all fs properties should have "xfs:" in the name to make
them look distinct, and defined "trusted.xfs:self_healing" as the
property that controls the amount of autonomous self healing.  There's a
new wrapper program "xfs_property" that one can use to administer the
properties.  xfs_scrub{,bed} uses the property; and mkfs.xfs can set it
for you at format time.

# mkfs.xfs -m self_healing /dev/sda

# xfs_property /dev/sda get self_healing
repair

# mount /dev/sda /mnt

# xfs_property /mnt set self_healing=check

# xfs_scrub -o fsprops_advise /mnt
Info: /mnt: Checking per self_healing directive.

--D

[1] https://lore.kernel.org/linux-xfs/20240724213852.GA612460@frogsfrogsfrogs/

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

* [PATCHSET v30.9 1/3] xfsprogs: filesystem properties
  2024-07-30  3:10 [RFC PATCHSET] xfsprogs: filesystem properties Darrick J. Wong
@ 2024-07-30  3:18 ` Darrick J. Wong
  2024-07-30  3:19   ` [PATCH 1/7] libfrog: support editing filesystem property sets Darrick J. Wong
                     ` (6 more replies)
  2024-07-30  3:19 ` [PATCHSET v30.9 2/3] xfs_scrub: control of autonomous self healing Darrick J. Wong
                   ` (3 subsequent siblings)
  4 siblings, 7 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:18 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

Hi all,

It would be very useful if system administrators could set properties for a
given xfs filesystem to control its behavior.  This we can do easily and
extensibly by setting ATTR_ROOT (aka "trusted") extended attributes on the root
directory.  To prevent this from becoming a weird free for all, let's add some
library and tooling support so that sysadmins simply run the xfs_property
program to administer these properties.

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

This has been running on the djcloud for months with no problems.  Enjoy!
Comments and questions are, as always, welcome.

--D

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=filesystem-properties

fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=filesystem-properties
---
Commits in this patchset:
 * libfrog: support editing filesystem property sets
 * xfs_spaceman: edit filesystem properties
 * xfs_db: improve getting and setting extended attributes
 * libxfs: hoist listxattr from xfs_repair
 * libxfs: pass a transaction context through listxattr
 * xfs_db: add a command to list xattrs
 * xfs_property: add a new tool to administer fs properties
---
 db/attrset.c            |  463 ++++++++++++++++++++++++++++++++++++++++++++++-
 libfrog/Makefile        |    7 +
 libfrog/fsproperties.c  |   39 ++++
 libfrog/fsproperties.h  |   50 +++++
 libfrog/fsprops.c       |  214 ++++++++++++++++++++++
 libfrog/fsprops.h       |   34 +++
 libxfs/Makefile         |    2 
 libxfs/listxattr.c      |   42 ++--
 libxfs/listxattr.h      |   17 ++
 man/man8/xfs_db.8       |   68 +++++++
 man/man8/xfs_property.8 |   52 +++++
 man/man8/xfs_spaceman.8 |   27 +++
 repair/Makefile         |    2 
 repair/listxattr.h      |   15 --
 repair/pptr.c           |    9 +
 spaceman/Makefile       |    7 +
 spaceman/init.c         |    1 
 spaceman/properties.c   |  342 +++++++++++++++++++++++++++++++++++
 spaceman/space.h        |    1 
 spaceman/xfs_property   |   77 ++++++++
 20 files changed, 1422 insertions(+), 47 deletions(-)
 create mode 100644 libfrog/fsproperties.c
 create mode 100644 libfrog/fsproperties.h
 create mode 100644 libfrog/fsprops.c
 create mode 100644 libfrog/fsprops.h
 rename repair/listxattr.c => libxfs/listxattr.c (84%)
 create mode 100644 libxfs/listxattr.h
 create mode 100644 man/man8/xfs_property.8
 delete mode 100644 repair/listxattr.h
 create mode 100644 spaceman/properties.c
 create mode 100755 spaceman/xfs_property


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

* [PATCHSET v30.9 2/3] xfs_scrub: control of autonomous self healing
  2024-07-30  3:10 [RFC PATCHSET] xfsprogs: filesystem properties Darrick J. Wong
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
@ 2024-07-30  3:19 ` Darrick J. Wong
  2024-07-30  3:21   ` [PATCH 1/3] libfrog: define a self_healing filesystem property Darrick J. Wong
                     ` (2 more replies)
  2024-07-30  3:19 ` [PATCHSET v30.9 3/3] xfs_scrub: separate package for self healing Darrick J. Wong
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:19 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

Hi all,

Now that we have the ability to set per-filesystem properties, teach the
background xfs_scrub service to pick up advice from the filesystem that it
wants to examine, and pick a mode from that.

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

This has been running on the djcloud for months with no problems.  Enjoy!
Comments and questions are, as always, welcome.

--D

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=self-healing
---
Commits in this patchset:
 * libfrog: define a self_healing filesystem property
 * xfs_scrub: allow sysadmin to control background scrubs
 * mkfs: set self_healing property
---
 libfrog/fsproperties.c |   38 +++++++++++++++
 libfrog/fsproperties.h |   13 +++++
 man/man8/mkfs.xfs.8.in |    6 ++
 man/man8/xfs_scrub.8   |   44 +++++++++++++++++
 mkfs/lts_4.19.conf     |    1 
 mkfs/lts_5.10.conf     |    1 
 mkfs/lts_5.15.conf     |    1 
 mkfs/lts_5.4.conf      |    1 
 mkfs/lts_6.1.conf      |    1 
 mkfs/lts_6.6.conf      |    1 
 mkfs/xfs_mkfs.c        |  122 ++++++++++++++++++++++++++++++++++++++++++++++++
 scrub/phase1.c         |   81 ++++++++++++++++++++++++++++++++
 scrub/xfs_scrub.c      |   14 ++++++
 scrub/xfs_scrub.h      |    7 +++
 14 files changed, 330 insertions(+), 1 deletion(-)


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

* [PATCHSET v30.9 3/3] xfs_scrub: separate package for self healing
  2024-07-30  3:10 [RFC PATCHSET] xfsprogs: filesystem properties Darrick J. Wong
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
  2024-07-30  3:19 ` [PATCHSET v30.9 2/3] xfs_scrub: control of autonomous self healing Darrick J. Wong
@ 2024-07-30  3:19 ` Darrick J. Wong
  2024-07-30  3:22   ` [PATCH 1/3] misc: shift install targets Darrick J. Wong
                     ` (2 more replies)
  2024-07-30  3:19 ` [PATCHSET v30.9] fstests: xfs filesystem properties Darrick J. Wong
  2024-08-02  0:29 ` [RFC PATCHSET] xfsprogs: " Dave Chinner
  4 siblings, 3 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:19 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

Hi all,

Debian policy (section 9 iirc) says that services shipped in a package should
be started by default.  We don't necessarily want that from the base xfsprogs
package long term, so separate the self healing services into a separate
package.

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

This has been running on the djcloud for months with no problems.  Enjoy!
Comments and questions are, as always, welcome.

--D

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=scrub-self-healing-package
---
Commits in this patchset:
 * misc: shift install targets
 * xfs_scrub: use the self_healing fsproperty to select mode
 * debian: create a new package for automatic self-healing
---
 Makefile                          |   14 +++++++++++---
 copy/Makefile                     |    6 +++++-
 db/Makefile                       |    6 +++++-
 debian/Makefile                   |    6 +++++-
 debian/control                    |    8 ++++++++
 debian/rules                      |   15 ++++++++++-----
 doc/Makefile                      |    7 ++++++-
 estimate/Makefile                 |    6 +++++-
 fsck/Makefile                     |    7 ++++++-
 fsr/Makefile                      |    6 +++++-
 growfs/Makefile                   |    6 +++++-
 include/Makefile                  |    7 ++++++-
 io/Makefile                       |    6 +++++-
 libfrog/Makefile                  |    4 +++-
 libhandle/Makefile                |    6 +++++-
 libxcmd/Makefile                  |    4 +++-
 libxfs/Makefile                   |    7 ++++++-
 libxlog/Makefile                  |    4 +++-
 logprint/Makefile                 |    6 +++++-
 m4/Makefile                       |    4 +++-
 man/Makefile                      |   10 +++++++---
 man/man2/Makefile                 |    4 +++-
 man/man3/Makefile                 |    4 +++-
 man/man5/Makefile                 |    5 ++++-
 man/man8/Makefile                 |    4 +++-
 mdrestore/Makefile                |    6 +++++-
 mkfs/Makefile                     |    6 +++++-
 po/Makefile                       |    7 ++++++-
 quota/Makefile                    |    6 +++++-
 repair/Makefile                   |    6 +++++-
 rtcp/Makefile                     |    6 +++++-
 scrub/Makefile                    |   19 ++++++++++++++-----
 scrub/xfs_scrub@.service.in       |    2 +-
 scrub/xfs_scrub_media@.service.in |    2 +-
 spaceman/Makefile                 |    6 +++++-
 35 files changed, 182 insertions(+), 46 deletions(-)


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

* [PATCHSET v30.9] fstests: xfs filesystem properties
  2024-07-30  3:10 [RFC PATCHSET] xfsprogs: filesystem properties Darrick J. Wong
                   ` (2 preceding siblings ...)
  2024-07-30  3:19 ` [PATCHSET v30.9 3/3] xfs_scrub: separate package for self healing Darrick J. Wong
@ 2024-07-30  3:19 ` Darrick J. Wong
  2024-07-30  3:23   ` [PATCH 1/1] xfs: functional testing for " Darrick J. Wong
  2024-07-30  3:25   ` [PATCHSET v30.9] fstests: xfs " Darrick J. Wong
  2024-08-02  0:29 ` [RFC PATCHSET] xfsprogs: " Dave Chinner
  4 siblings, 2 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:19 UTC (permalink / raw)
  To: zlang, djwong; +Cc: linux-xfs, fstests

Hi all,

It would be very useful if system administrators could set properties for a
given xfs filesystem to control its behavior.  This we can do easily and
extensibly by setting ATTR_ROOT (aka "trusted") extended attributes on the root
directory.  To prevent this from becoming a weird free for all, let's add some
library and tooling support so that sysadmins simply run the xfs_property
program to administer these properties.

If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.

This has been running on the djcloud for months with no problems.  Enjoy!
Comments and questions are, as always, welcome.

--D

xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=filesystem-properties

fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=filesystem-properties
---
Commits in this patchset:
 * xfs: functional testing for filesystem properties
---
 common/config      |    1 
 common/xfs         |    4 +-
 tests/xfs/1886     |  135 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/1886.out |   53 ++++++++++++++++++++
 tests/xfs/1887     |  124 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/1887.out |   46 ++++++++++++++++++
 tests/xfs/1888     |   66 +++++++++++++++++++++++++
 tests/xfs/1888.out |    9 +++
 tests/xfs/1889     |   67 ++++++++++++++++++++++++++
 tests/xfs/1889.out |    9 +++
 10 files changed, 512 insertions(+), 2 deletions(-)
 create mode 100755 tests/xfs/1886
 create mode 100644 tests/xfs/1886.out
 create mode 100755 tests/xfs/1887
 create mode 100644 tests/xfs/1887.out
 create mode 100755 tests/xfs/1888
 create mode 100644 tests/xfs/1888.out
 create mode 100755 tests/xfs/1889
 create mode 100644 tests/xfs/1889.out


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

* [PATCH 1/7] libfrog: support editing filesystem property sets
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
@ 2024-07-30  3:19   ` Darrick J. Wong
  2024-07-30 21:40     ` Christoph Hellwig
  2024-07-30  3:20   ` [PATCH 2/7] xfs_spaceman: edit filesystem properties Darrick J. Wong
                     ` (5 subsequent siblings)
  6 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:19 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Add some library functions so that spaceman and scrub can share the same
code to edit and retrieve filesystem properties.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 libfrog/Makefile       |    7 ++
 libfrog/fsproperties.c |   39 +++++++++
 libfrog/fsproperties.h |   50 +++++++++++
 libfrog/fsprops.c      |  214 ++++++++++++++++++++++++++++++++++++++++++++++++
 libfrog/fsprops.h      |   34 ++++++++
 5 files changed, 344 insertions(+)
 create mode 100644 libfrog/fsproperties.c
 create mode 100644 libfrog/fsproperties.h
 create mode 100644 libfrog/fsprops.c
 create mode 100644 libfrog/fsprops.h


diff --git a/libfrog/Makefile b/libfrog/Makefile
index 0b5b23893a13..acddc894ee93 100644
--- a/libfrog/Makefile
+++ b/libfrog/Makefile
@@ -20,6 +20,7 @@ convert.c \
 crc32.c \
 file_exchange.c \
 fsgeom.c \
+fsproperties.c \
 getparents.c \
 histogram.c \
 list_sort.c \
@@ -47,6 +48,7 @@ dahashselftest.h \
 div64.h \
 file_exchange.h \
 fsgeom.h \
+fsproperties.h \
 getparents.h \
 histogram.h \
 logging.h \
@@ -60,6 +62,11 @@ workqueue.h
 
 LSRCFILES += gen_crc32table.c
 
+ifeq ($(HAVE_LIBATTR),yes)
+CFILES+=fsprops.c
+HFILES+=fsprops.h
+endif
+
 LDIRT = gen_crc32table crc32table.h
 
 default: ltdepend $(LTLIBRARY)
diff --git a/libfrog/fsproperties.c b/libfrog/fsproperties.c
new file mode 100644
index 000000000000..c317d15c1de0
--- /dev/null
+++ b/libfrog/fsproperties.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include <string.h>
+#include "xfs.h"
+#include "libfrog/fsgeom.h"
+#include "libfrog/fsproperties.h"
+#include "list.h"
+
+/* Return the offset of a string in a string table, or -1 if not found. */
+static inline int
+__fsprops_lookup(
+	const char	*values[],
+	unsigned int	nr_values,
+	const char	*value)
+{
+	unsigned int	i;
+
+	for (i = 0; i < nr_values; i++) {
+		if (values[i] && !strcmp(value, values[i]))
+			return i;
+	}
+
+	return -1;
+}
+
+#define fsprops_lookup(values, value) \
+	__fsprops_lookup((values), ARRAY_SIZE(values), (value))
+
+/* Return true if a fs property name=value tuple is allowed. */
+bool
+fsprop_validate(
+	const char	*name,
+	const char	*value)
+{
+	return true;
+}
diff --git a/libfrog/fsproperties.h b/libfrog/fsproperties.h
new file mode 100644
index 000000000000..6dee8259a437
--- /dev/null
+++ b/libfrog/fsproperties.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2024 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#ifndef __LIBFROG_FSPROPERTIES_H__
+#define __LIBFROG_FSPROPERTIES_H__
+
+/* Name space for filesystem properties. */
+#define XFS_FSPROPS_NS		"trusted"
+
+/*
+ * All filesystem property xattr names must have this string after the
+ * namespace.  For example, the VFS xattr calls should use the name
+ * "trusted.xfs:fubar".  The xfs xattr ioctls would set ATTR_ROOT and use the
+ * name "xfs:fubar".
+ */
+#define XFS_FSPROPS_PREFIX	"xfs:"
+
+static inline int
+fsprop_name_to_attr_name(
+	const char		*prop_name,
+	char			**attr_name)
+{
+	return asprintf(attr_name, XFS_FSPROPS_PREFIX "%s", prop_name);
+}
+
+static inline const char *
+attr_name_to_fsprop_name(
+	const char		*attr_name)
+{
+	const size_t		bytes = sizeof(XFS_FSPROPS_PREFIX) - 1;
+	unsigned int		i;
+
+	for (i = 0; i < bytes; i++) {
+		if (attr_name[i] == 0)
+			return NULL;
+	}
+
+	if (memcmp(attr_name, XFS_FSPROPS_PREFIX, bytes) != 0)
+		return NULL;
+
+	return attr_name + bytes;
+}
+
+bool fsprop_validate(const char *name, const char *value);
+
+/* Specific Filesystem Properties */
+
+#endif /* __LIBFROG_FSPROPERTIES_H__ */
diff --git a/libfrog/fsprops.c b/libfrog/fsprops.c
new file mode 100644
index 000000000000..d6d143efe027
--- /dev/null
+++ b/libfrog/fsprops.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "xfs.h"
+#include "handle.h"
+#include "libfrog/fsgeom.h"
+#include "libfrog/paths.h"
+#include "libfrog/bulkstat.h"
+#include "libfrog/fsprops.h"
+#include "libfrog/fsproperties.h"
+
+#include <attr/attributes.h>
+
+/*
+ * Given an xfd and a mount table path, get us the handle for the root dir so
+ * we can set filesystem properties.
+ */
+int
+fsprops_open_handle(
+	struct xfs_fd		*xfd,
+	struct fs_path		*fs_path,
+	struct fsprops_handle	*fph)
+{
+	struct xfs_bulkstat	bulkstat;
+	struct stat		sb;
+	int			fd;
+	int			ret;
+
+	/* fs properties only supported on V5 filesystems */
+	if (!(xfd->fsgeom.flags & XFS_FSOP_GEOM_FLAGS_V5SB)) {
+		errno = EOPNOTSUPP;
+		return -1;
+	}
+
+	ret = -xfrog_bulkstat_single(xfd, XFS_BULK_IREQ_SPECIAL_ROOT,
+			XFS_BULK_IREQ_SPECIAL, &bulkstat);
+	if (ret)
+		return ret;
+
+	fd = open(fs_path->fs_dir, O_RDONLY | O_DIRECTORY);
+	if (fd < 0)
+		return -1;
+
+	ret = fstat(fd, &sb);
+	if (ret)
+		goto out_fd;
+
+	if (sb.st_ino != bulkstat.bs_ino) {
+		errno = ESRMNT;
+		ret = -1;
+		goto out_fd;
+	}
+
+	ret = fd_to_handle(fd, &fph->hanp, &fph->hlen);
+	if (ret)
+		goto out_fd;
+
+out_fd:
+	close(fd);
+	return ret;
+}
+
+/* Free a fsproperties handle. */
+void
+fsprops_free_handle(
+	struct fsprops_handle	*fph)
+{
+	if (fph->hanp)
+		free_handle(fph->hanp, fph->hlen);
+	fph->hanp = NULL;
+	fph->hlen = 0;
+}
+
+/* Call the given callback on every fs property accessible through the handle. */
+int
+fsprops_walk_names(
+	struct fsprops_handle	*fph,
+	fsprops_name_walk_fn	walk_fn,
+	void			*priv)
+{
+	struct attrlist_cursor	cur = { };
+	char			attrbuf[XFS_XATTR_LIST_MAX];
+	struct attrlist		*attrlist = (struct attrlist *)attrbuf;
+	int			ret;
+
+	memset(attrbuf, 0, XFS_XATTR_LIST_MAX);
+
+	while ((ret = attr_list_by_handle(fph->hanp, fph->hlen, attrbuf,
+				XFS_XATTR_LIST_MAX, XFS_IOC_ATTR_ROOT,
+				&cur)) == 0) {
+		unsigned int	i;
+
+		for (i = 0; i < attrlist->al_count; i++) {
+			struct attrlist_ent	*ent = ATTR_ENTRY(attrlist, i);
+			const char		*p =
+				attr_name_to_fsprop_name(ent->a_name);
+
+			if (p) {
+				ret = walk_fn(fph, p, ent->a_valuelen, priv);
+				if (ret)
+					break;
+			}
+		}
+
+		if (!attrlist->al_more)
+			break;
+	}
+
+	return ret;
+}
+
+/* Retrieve the value of a specific fileystem property. */
+int
+fsprops_get(
+	struct fsprops_handle	*fph,
+	const char		*name,
+	void			*valuebuf,
+	size_t			*valuelen)
+{
+	struct xfs_attr_multiop	ops = {
+		.am_opcode	= ATTR_OP_GET,
+		.am_attrvalue	= valuebuf,
+		.am_length	= *valuelen,
+		.am_flags	= XFS_IOC_ATTR_ROOT,
+	};
+	int			ret;
+
+	ret = fsprop_name_to_attr_name(name, (char **)&ops.am_attrname);
+	if (ret < 0)
+		return ret;
+
+	ret = attr_multi_by_handle(fph->hanp, fph->hlen, &ops, 1, 0);
+	if (ret < 0)
+		goto out_name;
+
+	if (ops.am_error) {
+		errno = -ops.am_error;
+		ret = -1;
+		goto out_name;
+	}
+
+	*valuelen = ops.am_length;
+out_name:
+	free(ops.am_attrname);
+	return ret;
+}
+
+/* Set the value of a specific fileystem property. */
+int
+fsprops_set(
+	struct fsprops_handle	*fph,
+	const char		*name,
+	void			*valuebuf,
+	size_t			valuelen)
+{
+	struct xfs_attr_multiop	ops = {
+		.am_opcode	= ATTR_OP_SET,
+		.am_attrvalue	= valuebuf,
+		.am_length	= valuelen,
+		.am_flags	= XFS_IOC_ATTR_ROOT,
+	};
+	int			ret;
+
+	ret = fsprop_name_to_attr_name(name, (char **)&ops.am_attrname);
+	if (ret < 0)
+		return ret;
+
+	ret = attr_multi_by_handle(fph->hanp, fph->hlen, &ops, 1, 0);
+	if (ret < 0)
+		goto out_name;
+
+	if (ops.am_error) {
+		errno = -ops.am_error;
+		ret = -1;
+		goto out_name;
+	}
+
+out_name:
+	free(ops.am_attrname);
+	return ret;
+}
+
+/* Unset the value of a specific fileystem property. */
+int
+fsprops_remove(
+	struct fsprops_handle	*fph,
+	const char		*name)
+{
+	struct xfs_attr_multiop	ops = {
+		.am_opcode	= ATTR_OP_REMOVE,
+		.am_flags	= XFS_IOC_ATTR_ROOT,
+	};
+	int			ret;
+
+	ret = fsprop_name_to_attr_name(name, (char **)&ops.am_attrname);
+	if (ret < 0)
+		return ret;
+
+	ret = attr_multi_by_handle(fph->hanp, fph->hlen, &ops, 1, 0);
+	if (ret < 0)
+		goto out_name;
+
+	if (ops.am_error) {
+		errno = -ops.am_error;
+		ret = -1;
+		goto out_name;
+	}
+
+out_name:
+	free(ops.am_attrname);
+	return ret;
+}
diff --git a/libfrog/fsprops.h b/libfrog/fsprops.h
new file mode 100644
index 000000000000..9276f2425191
--- /dev/null
+++ b/libfrog/fsprops.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2024 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#ifndef __LIBFROG_FSPROPS_H__
+#define __LIBFROG_FSPROPS_H__
+
+/* Edit and view filesystem property sets. */
+
+struct fsprops_handle {
+	void	*hanp;
+	size_t	hlen;
+};
+
+struct xfs_fd;
+struct fs_path;
+
+int fsprops_open_handle(struct xfs_fd *xfd, struct fs_path *fspath,
+		struct fsprops_handle *fph);
+void fsprops_free_handle(struct fsprops_handle *fph);
+
+typedef int (*fsprops_name_walk_fn)(struct fsprops_handle *fph,
+		const char *name, size_t valuelen, void *priv);
+
+int fsprops_walk_names(struct fsprops_handle *fph, fsprops_name_walk_fn walk_fn,
+		void *priv);
+int fsprops_get(struct fsprops_handle *fph, const char *name, void *attrbuf,
+		size_t *attrlen);
+int fsprops_set(struct fsprops_handle *fph, const char *name, void *attrbuf,
+		size_t attrlen);
+int fsprops_remove(struct fsprops_handle *fph, const char *name);
+
+#endif /* __LIBFROG_FSPROPS_H__ */


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

* [PATCH 2/7] xfs_spaceman: edit filesystem properties
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
  2024-07-30  3:19   ` [PATCH 1/7] libfrog: support editing filesystem property sets Darrick J. Wong
@ 2024-07-30  3:20   ` Darrick J. Wong
  2024-07-30 21:41     ` Christoph Hellwig
  2024-07-30  3:20   ` [PATCH 3/7] xfs_db: improve getting and setting extended attributes Darrick J. Wong
                     ` (4 subsequent siblings)
  6 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:20 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Add some new subcommands to xfs_spaceman so that we can examine
filesystem properties.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 man/man8/xfs_spaceman.8 |   27 ++++
 spaceman/Makefile       |    4 +
 spaceman/init.c         |    1 
 spaceman/properties.c   |  342 +++++++++++++++++++++++++++++++++++++++++++++++
 spaceman/space.h        |    1 
 5 files changed, 375 insertions(+)
 create mode 100644 spaceman/properties.c


diff --git a/man/man8/xfs_spaceman.8 b/man/man8/xfs_spaceman.8
index 0d299132a788..4615774de59e 100644
--- a/man/man8/xfs_spaceman.8
+++ b/man/man8/xfs_spaceman.8
@@ -217,3 +217,30 @@ Do not trim free space extents shorter than this length.
 Units can be appended to this argument.
 .PD
 .RE
+
+.SH FILESYSTEM PROPERTIES
+If the opened file is the root directory of a filesystem, the following
+commands can be used to read and write filesystem properties.
+These properties allow system administrators to express their preferences for
+the filesystem in question.
+.TP
+.BI "getfsprops name [ " names "... ]"
+Retrieve the values of the given filesystem properties.
+.TP
+.BI "listfsprops"
+List all filesystem properties that have been stored in the filesystem.
+.TP
+.BI "setfsprops " name = value " [ " name = value "... ]"
+Set the given filesystem properties to the specified values.
+.TP
+.BI "removefsprops name [ " names "... ]"
+Remove the given filesystem properties.
+
+.RE
+Currently supported filesystem properties are:
+.TP
+.B self_healing
+See the
+.BR xfs_scrub (8)
+manual for more information.
+.RE
diff --git a/spaceman/Makefile b/spaceman/Makefile
index 358db9edf5cb..2688b37c770d 100644
--- a/spaceman/Makefile
+++ b/spaceman/Makefile
@@ -30,6 +30,10 @@ ifeq ($(HAVE_GETFSMAP),yes)
 CFILES += freesp.c
 endif
 
+ifeq ($(HAVE_LIBATTR),yes)
+CFILES += properties.c
+endif
+
 default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
diff --git a/spaceman/init.c b/spaceman/init.c
index cf1ff3cbb0ee..aff666cdb670 100644
--- a/spaceman/init.c
+++ b/spaceman/init.c
@@ -35,6 +35,7 @@ init_commands(void)
 	trim_init();
 	freesp_init();
 	health_init();
+	fsprops_init();
 }
 
 static int
diff --git a/spaceman/properties.c b/spaceman/properties.c
new file mode 100644
index 000000000000..dbe628c1184a
--- /dev/null
+++ b/spaceman/properties.c
@@ -0,0 +1,342 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "platform_defs.h"
+#include "command.h"
+#include "init.h"
+#include "libfrog/paths.h"
+#include "input.h"
+#include "libfrog/fsgeom.h"
+#include "handle.h"
+#include "space.h"
+#include "libfrog/fsprops.h"
+#include "libfrog/fsproperties.h"
+
+#include <attr/attributes.h>
+
+static void
+listfsprops_help(void)
+{
+	printf(_(
+"Print the names of the filesystem properties stored in this filesystem.\n"
+"\n"));
+}
+
+static int
+print_fsprop(
+	struct fsprops_handle	*fph,
+	const char		*name,
+	size_t			unused,
+	void			*priv)
+{
+	bool			*print_values = priv;
+	char			valuebuf[ATTR_MAX_VALUELEN];
+	size_t			valuelen = ATTR_MAX_VALUELEN;
+	int			ret;
+
+	if (!(*print_values)) {
+		printf("%s\n", name);
+		return 0;
+	}
+
+	ret = fsprops_get(fph, name, valuebuf, &valuelen);
+	if (ret)
+		return ret;
+
+	printf("%s=%.*s\n", name, (int)valuelen, valuebuf);
+	return 0;
+}
+
+static int
+listfsprops_f(
+	int			argc,
+	char			**argv)
+{
+	struct fsprops_handle	fph = { };
+	bool			print_values = false;
+	int			c;
+	int			ret;
+
+	while ((c = getopt(argc, argv, "v")) != EOF) {
+		switch (c) {
+		case 'v':
+			print_values = true;
+			break;
+		default:
+			exitcode = 1;
+			listfsprops_help();
+			return 0;
+		}
+	}
+
+	ret = fsprops_open_handle(&file->xfd, &file->fs_path, &fph);
+	if (ret) {
+		if (errno == ESRMNT)
+			fprintf(stderr,
+ _("%s: Cannot find alleged XFS mount point %s.\n"),
+					file->name, file->fs_path.fs_dir);
+		else
+			perror(file->name);
+		exitcode = 1;
+		return 0;
+	}
+
+	ret = fsprops_walk_names(&fph, print_fsprop, &print_values);
+	if (ret) {
+		perror(file->name);
+		exitcode = 1;
+	}
+
+	fsprops_free_handle(&fph);
+	return 0;
+}
+
+static struct cmdinfo listfsprops_cmd = {
+	.name		= "listfsprops",
+	.cfunc		= listfsprops_f,
+	.argmin		= 0,
+	.argmax		= -1,
+	.flags		= CMD_FLAG_ONESHOT,
+	.args		= "",
+	.help		= listfsprops_help,
+};
+
+static void
+getfsprops_help(void)
+{
+	printf(_(
+"Print the values of filesystem properties stored in this filesystem.\n"
+"\n"
+"Pass property names as the arguments.\n"
+"\n"));
+}
+
+static int
+getfsprops_f(
+	int			argc,
+	char			**argv)
+{
+	struct fsprops_handle	fph = { };
+	int			c;
+	int			ret;
+
+	while ((c = getopt(argc, argv, "")) != EOF) {
+		switch (c) {
+		default:
+			exitcode = 1;
+			getfsprops_help();
+			return 0;
+		}
+	}
+
+	ret = fsprops_open_handle(&file->xfd, &file->fs_path, &fph);
+	if (ret) {
+		if (errno == ESRMNT)
+			fprintf(stderr,
+ _("%s: Cannot find alleged XFS mount point %s.\n"),
+					file->name, file->fs_path.fs_dir);
+		else
+			perror(file->name);
+		exitcode = 1;
+		return 0;
+	}
+
+	for (c = optind; c < argc; c++) {
+		char		valuebuf[ATTR_MAX_VALUELEN];
+		size_t		valuelen = ATTR_MAX_VALUELEN;
+
+		ret = fsprops_get(&fph, argv[c], valuebuf, &valuelen);
+		if (ret) {
+			perror(argv[c]);
+			exitcode = 1;
+			break;
+		}
+
+		printf("%s=%.*s\n", argv[c], (int)valuelen, valuebuf);
+	}
+
+	fsprops_free_handle(&fph);
+	return 0;
+}
+
+static struct cmdinfo getfsprops_cmd = {
+	.name		= "getfsprops",
+	.cfunc		= getfsprops_f,
+	.argmin		= 0,
+	.argmax		= -1,
+	.flags		= CMD_FLAG_ONESHOT,
+	.args		= "",
+	.help		= getfsprops_help,
+};
+
+static void
+setfsprops_help(void)
+{
+	printf(_(
+"Set values of filesystem properties stored in this filesystem.\n"
+"\n"
+" -f    Do not try to validate property value.\n"
+"\n"
+"Provide name=value tuples as the arguments.\n"
+"\n"));
+}
+
+static int
+setfsprops_f(
+	int			argc,
+	char			**argv)
+{
+	struct fsprops_handle	fph = { };
+	bool			force = false;
+	int			c;
+	int			ret;
+
+	while ((c = getopt(argc, argv, "f")) != EOF) {
+		switch (c) {
+		case 'f':
+			force = true;
+			break;
+		default:
+			exitcode = 1;
+			getfsprops_help();
+			return 0;
+		}
+	}
+
+	ret = fsprops_open_handle(&file->xfd, &file->fs_path, &fph);
+	if (ret) {
+		if (errno == ESRMNT)
+			fprintf(stderr,
+ _("%s: Cannot find alleged XFS mount point %s.\n"),
+					file->name, file->fs_path.fs_dir);
+		else
+			perror(file->name);
+		exitcode = 1;
+		return 0;
+	}
+
+	for (c = optind; c < argc; c ++) {
+		char	*equals = strchr(argv[c], '=');
+
+		if (!equals) {
+			fprintf(stderr, _("%s: property value required.\n"),
+					argv[c]);
+			exitcode = 1;
+			break;
+		}
+
+		*equals = 0;
+
+		if (!force && !fsprop_validate(argv[c], equals + 1)) {
+			fprintf(stderr, _("%s: invalid value \"%s\".\n"),
+					argv[c], equals + 1);
+			*equals = '=';
+			exitcode = 1;
+			break;
+		}
+
+		ret = fsprops_set(&fph, argv[c], equals + 1,
+				strlen(equals + 1));
+		if (ret) {
+			perror(argv[c]);
+			*equals = '=';
+			exitcode = 1;
+			break;
+		}
+
+		printf("%s=%s\n", argv[c], equals + 1);
+		*equals = '=';
+	}
+
+	fsprops_free_handle(&fph);
+	return 0;
+}
+
+static struct cmdinfo setfsprops_cmd = {
+	.name		= "setfsprops",
+	.cfunc		= setfsprops_f,
+	.argmin		= 0,
+	.argmax		= -1,
+	.flags		= CMD_FLAG_ONESHOT,
+	.args		= "",
+	.help		= setfsprops_help,
+};
+
+static void
+removefsprops_help(void)
+{
+	printf(_(
+"Unset a filesystem property.\n"
+"\n"
+"Pass property names as the arguments.\n"
+"\n"));
+}
+
+static int
+removefsprops_f(
+	int			argc,
+	char			**argv)
+{
+	struct fsprops_handle	fph = { };
+	int			c;
+	int			ret;
+
+	while ((c = getopt(argc, argv, "")) != EOF) {
+		switch (c) {
+		default:
+			exitcode = 1;
+			getfsprops_help();
+			return 0;
+		}
+	}
+
+	ret = fsprops_open_handle(&file->xfd, &file->fs_path, &fph);
+	if (ret) {
+		if (errno == ESRMNT)
+			fprintf(stderr,
+ _("%s: Cannot find alleged XFS mount point %s.\n"),
+					file->name, file->fs_path.fs_dir);
+		else
+			perror(file->name);
+		exitcode = 1;
+		return 0;
+	}
+
+	for (c = optind; c < argc; c++) {
+		ret = fsprops_remove(&fph, argv[c]);
+		if (ret) {
+			perror(argv[c]);
+			exitcode = 1;
+			break;
+		}
+	}
+
+	fsprops_free_handle(&fph);
+	return 0;
+}
+
+static struct cmdinfo removefsprops_cmd = {
+	.name		= "removefsprops",
+	.cfunc		= removefsprops_f,
+	.argmin		= 0,
+	.argmax		= -1,
+	.flags		= CMD_FLAG_ONESHOT,
+	.args		= "",
+	.help		= removefsprops_help,
+};
+
+void
+fsprops_init(void)
+{
+	listfsprops_cmd.oneline = _("list file system properties");
+	getfsprops_cmd.oneline = _("print file system properties");
+	setfsprops_cmd.oneline = _("set file system properties");
+	removefsprops_cmd.oneline = _("unset file system properties");
+
+	add_command(&listfsprops_cmd);
+	add_command(&getfsprops_cmd);
+	add_command(&setfsprops_cmd);
+	add_command(&removefsprops_cmd);
+}
diff --git a/spaceman/space.h b/spaceman/space.h
index 28fa35a30479..c4beb5f489ff 100644
--- a/spaceman/space.h
+++ b/spaceman/space.h
@@ -36,5 +36,6 @@ extern void	freesp_init(void);
 #endif
 extern void	info_init(void);
 extern void	health_init(void);
+void		fsprops_init(void);
 
 #endif /* XFS_SPACEMAN_SPACE_H_ */


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

* [PATCH 3/7] xfs_db: improve getting and setting extended attributes
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
  2024-07-30  3:19   ` [PATCH 1/7] libfrog: support editing filesystem property sets Darrick J. Wong
  2024-07-30  3:20   ` [PATCH 2/7] xfs_spaceman: edit filesystem properties Darrick J. Wong
@ 2024-07-30  3:20   ` Darrick J. Wong
  2024-07-30 21:37     ` Christoph Hellwig
  2024-07-30  3:20   ` [PATCH 4/7] libxfs: hoist listxattr from xfs_repair Darrick J. Wong
                     ` (3 subsequent siblings)
  6 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:20 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Add an attr_get command to retrieve the value of an xattr from a file;
and extend the attr_set command to allow passing of string values.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 db/attrset.c      |  262 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 man/man8/xfs_db.8 |   40 ++++++++
 2 files changed, 293 insertions(+), 9 deletions(-)


diff --git a/db/attrset.c b/db/attrset.c
index 81d530055193..4e7cca450322 100644
--- a/db/attrset.c
+++ b/db/attrset.c
@@ -17,20 +17,44 @@
 #include "inode.h"
 #include "malloc.h"
 #include <sys/xattr.h>
+#include "libfrog/fsproperties.h"
 
+static int		attr_get_f(int argc, char **argv);
 static int		attr_set_f(int argc, char **argv);
 static int		attr_remove_f(int argc, char **argv);
+static void		attrget_help(void);
 static void		attrset_help(void);
 
+static const cmdinfo_t	attr_get_cmd =
+	{ "attr_get", "aget", attr_get_f, 1, -1, 0,
+	  N_("[-r|-s|-u|-p|-Z] name"),
+	  N_("get the named attribute on the current inode"), attrget_help };
 static const cmdinfo_t	attr_set_cmd =
 	{ "attr_set", "aset", attr_set_f, 1, -1, 0,
-	  N_("[-r|-s|-u|-p] [-n] [-R|-C] [-v n] name"),
+	  N_("[-r|-s|-u|-p|-Z] [-n] [-R|-C] [-v n] name"),
 	  N_("set the named attribute on the current inode"), attrset_help };
 static const cmdinfo_t	attr_remove_cmd =
 	{ "attr_remove", "aremove", attr_remove_f, 1, -1, 0,
-	  N_("[-r|-s|-u|-p] [-n] name"),
+	  N_("[-r|-s|-u|-p|-Z] [-n] name"),
 	  N_("remove the named attribute from the current inode"), attrset_help };
 
+static void
+attrget_help(void)
+{
+	dbprintf(_(
+"\n"
+" The attr_get command provide interfaces for retrieving the values of extended\n"
+" attributes of a file.  This command requires attribute names to be specified.\n"
+" There are 4 namespace flags:\n"
+"  -r -- 'root'\n"
+"  -u -- 'user'		(default)\n"
+"  -s -- 'secure'\n"
+"  -p -- 'parent'\n"
+"  -f -- 'fs-verity'\n"
+"  -Z -- fs property\n"
+"\n"));
+}
+
 static void
 attrset_help(void)
 {
@@ -45,10 +69,15 @@ attrset_help(void)
 "  -u -- 'user'		(default)\n"
 "  -s -- 'secure'\n"
 "  -p -- 'parent'\n"
+"  -Z -- fs property\n"
 "\n"
 " For attr_set, these options further define the type of set operation:\n"
 "  -C -- 'create'    - create attribute, fail if it already exists\n"
 "  -R -- 'replace'   - replace attribute, fail if it does not exist\n"
+"\n"
+" If the attribute value is a string, it can be specified after the\n"
+" attribute name.\n"
+"\n"
 " The backward compatibility mode 'noattr2' can be emulated (-n) also.\n"
 "\n"));
 }
@@ -59,6 +88,7 @@ attrset_init(void)
 	if (!expert_mode)
 		return;
 
+	add_command(&attr_get_cmd);
 	add_command(&attr_set_cmd);
 	add_command(&attr_remove_cmd);
 }
@@ -106,6 +136,57 @@ get_buf_from_file(
 				 LIBXFS_ATTR_ROOT | \
 				 LIBXFS_ATTR_PARENT)
 
+static bool
+adjust_fsprop_attr_name(
+	struct xfs_da_args	*args,
+	bool			*free_name)
+{
+	const char		*o = args->name;
+	char			*p;
+	int			ret;
+
+	if ((args->attr_filter & LIBXFS_ATTR_NS) != LIBXFS_ATTR_ROOT) {
+		dbprintf(_("fs properties must be ATTR_ROOT\n"));
+		return false;
+	}
+
+	ret = fsprop_name_to_attr_name(o, &p);
+	if (ret < 0) {
+		dbprintf(_("could not allocate fs property name string\n"));
+		return false;
+	}
+	args->namelen = ret;
+	args->name = p;
+
+	if (*free_name)
+		free((void *)o);
+	*free_name = true;
+
+	if (args->namelen > MAXNAMELEN) {
+		dbprintf(_("%s: name too long\n"), args->name);
+		return false;
+	}
+
+	if (args->valuelen > ATTR_MAX_VALUELEN) {
+		dbprintf(_("%s: value too long\n"), args->name);
+		return false;
+	}
+
+	return true;
+}
+
+static void
+print_fsprop(
+	struct xfs_da_args	*args)
+{
+	const char		*p = attr_name_to_fsprop_name(args->name);
+
+	if (p)
+		printf("%s=%.*s\n", p, args->valuelen, (char *)args->value);
+	else
+		fprintf(stderr, _("%s: not a fs property?\n"), args->name);
+}
+
 static int
 attr_set_f(
 	int			argc,
@@ -119,7 +200,9 @@ attr_set_f(
 	char			*sp;
 	char			*name_from_file = NULL;
 	char			*value_from_file = NULL;
+	bool			free_name = false;
 	enum xfs_attr_update	op = XFS_ATTRUPDATE_UPSERT;
+	bool			fsprop = false;
 	int			c;
 	int			error;
 
@@ -132,9 +215,12 @@ attr_set_f(
 		return 0;
 	}
 
-	while ((c = getopt(argc, argv, "ruspCRnN:v:V:")) != EOF) {
+	while ((c = getopt(argc, argv, "ruspCRnN:v:V:Z")) != EOF) {
 		switch (c) {
 		/* namespaces */
+		case 'Z':
+			fsprop = true;
+			fallthrough;
 		case 'r':
 			args.attr_filter &= ~LIBXFS_ATTR_NS;
 			args.attr_filter |= LIBXFS_ATTR_ROOT;
@@ -213,9 +299,10 @@ attr_set_f(
 		if (!args.name)
 			return 0;
 
+		free_name = true;
 		args.namelen = namelen;
 	} else {
-		if (optind != argc - 1) {
+		if (optind != argc - 1 && optind != argc - 2) {
 			dbprintf(_("too few options for attr_set (no name given)\n"));
 			return 0;
 		}
@@ -250,6 +337,25 @@ attr_set_f(
 			goto out;
 		}
 		memset(args.value, 'v', args.valuelen);
+	} else if (optind == argc - 2) {
+		args.valuelen = strlen(argv[optind + 1]);
+		args.value = strdup(argv[optind + 1]);
+		if (!args.value) {
+			dbprintf(_("cannot allocate buffer (%d)\n"),
+					args.valuelen);
+			goto out;
+		}
+	}
+
+	if (fsprop) {
+		if (!fsprop_validate(args.name, args.value)) {
+			dbprintf(_("%s: invalid value \"%s\"\n"),
+					args.name, args.value);
+			goto out;
+		}
+
+		if (!adjust_fsprop_attr_name(&args, &free_name))
+			goto out;
 	}
 
 	if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &args.dp)) {
@@ -269,6 +375,9 @@ attr_set_f(
 		goto out;
 	}
 
+	if (fsprop)
+		print_fsprop(&args);
+
 	/* refresh with updated inode contents */
 	set_cur_inode(iocur_top->ino);
 
@@ -277,7 +386,7 @@ attr_set_f(
 		libxfs_irele(args.dp);
 	if (args.value)
 		free(args.value);
-	if (name_from_file)
+	if (free_name)
 		free((void *)args.name);
 	return 0;
 }
@@ -293,6 +402,8 @@ attr_remove_f(
 		.op_flags	= XFS_DA_OP_OKNOENT,
 	};
 	char			*name_from_file = NULL;
+	bool			free_name = false;
+	bool			fsprop = false;
 	int			c;
 	int			error;
 
@@ -305,9 +416,12 @@ attr_remove_f(
 		return 0;
 	}
 
-	while ((c = getopt(argc, argv, "ruspnN:")) != EOF) {
+	while ((c = getopt(argc, argv, "ruspnN:Z")) != EOF) {
 		switch (c) {
 		/* namespaces */
+		case 'Z':
+			fsprop = true;
+			fallthrough;
 		case 'r':
 			args.attr_filter &= ~LIBXFS_ATTR_NS;
 			args.attr_filter |= LIBXFS_ATTR_ROOT;
@@ -354,6 +468,7 @@ attr_remove_f(
 		if (!args.name)
 			return 0;
 
+		free_name = true;
 		args.namelen = namelen;
 	} else {
 		if (optind != argc - 1) {
@@ -374,6 +489,9 @@ attr_remove_f(
 		}
 	}
 
+	if (fsprop && !adjust_fsprop_attr_name(&args, &free_name))
+		goto out;
+
 	if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &args.dp)) {
 		dbprintf(_("failed to iget inode %llu\n"),
 			(unsigned long long)iocur_top->ino);
@@ -398,7 +516,137 @@ attr_remove_f(
 out:
 	if (args.dp)
 		libxfs_irele(args.dp);
-	if (name_from_file)
+	if (free_name)
+		free((void *)args.name);
+	return 0;
+}
+
+static int
+attr_get_f(
+	int			argc,
+	char			**argv)
+{
+	struct xfs_da_args	args = {
+		.geo		= mp->m_attr_geo,
+		.whichfork	= XFS_ATTR_FORK,
+		.op_flags	= XFS_DA_OP_OKNOENT,
+	};
+	char			*name_from_file = NULL;
+	bool			free_name = false;
+	bool			fsprop = false;
+	int			c;
+	int			error;
+
+	if (cur_typ == NULL) {
+		dbprintf(_("no current type\n"));
+		return 0;
+	}
+	if (cur_typ->typnm != TYP_INODE) {
+		dbprintf(_("current type is not inode\n"));
+		return 0;
+	}
+
+	while ((c = getopt(argc, argv, "ruspN:Z")) != EOF) {
+		switch (c) {
+		/* namespaces */
+		case 'Z':
+			fsprop = true;
+			fallthrough;
+		case 'r':
+			args.attr_filter &= ~LIBXFS_ATTR_NS;
+			args.attr_filter |= LIBXFS_ATTR_ROOT;
+			break;
+		case 'u':
+			args.attr_filter &= ~LIBXFS_ATTR_NS;
+			break;
+		case 's':
+			args.attr_filter &= ~LIBXFS_ATTR_NS;
+			args.attr_filter |= LIBXFS_ATTR_SECURE;
+			break;
+		case 'p':
+			args.attr_filter &= ~LIBXFS_ATTR_NS;
+			args.attr_filter |= XFS_ATTR_PARENT;
+			break;
+
+		case 'N':
+			name_from_file = optarg;
+			break;
+		default:
+			dbprintf(_("bad option for attr_get command\n"));
+			return 0;
+		}
+	}
+
+	if (name_from_file) {
+		int namelen;
+
+		if (optind != argc) {
+			dbprintf(_("too many options for attr_get (no name needed)\n"));
+			return 0;
+		}
+
+		args.name = get_buf_from_file(name_from_file, MAXNAMELEN,
+				&namelen);
+		if (!args.name)
+			return 0;
+
+		free_name = true;
+		args.namelen = namelen;
+	} else {
+		if (optind != argc - 1) {
+			dbprintf(_("too few options for attr_get (no name given)\n"));
+			return 0;
+		}
+
+		args.name = (const unsigned char *)argv[optind];
+		if (!args.name) {
+			dbprintf(_("invalid name\n"));
+			return 0;
+		}
+
+		args.namelen = strlen(argv[optind]);
+		if (args.namelen >= MAXNAMELEN) {
+			dbprintf(_("name too long\n"));
+			goto out;
+		}
+	}
+
+	if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &args.dp)) {
+		dbprintf(_("failed to iget inode %llu\n"),
+			(unsigned long long)iocur_top->ino);
+		goto out;
+	}
+
+	if (fsprop && !adjust_fsprop_attr_name(&args, &free_name))
+		goto out;
+
+	args.owner = iocur_top->ino;
+	libxfs_attr_sethash(&args);
+
+	/*
+	 * Look up attr value with a maximally long length and a null buffer
+	 * to return the value and the correct length.
+	 */
+	args.valuelen = XATTR_SIZE_MAX;
+	error = -libxfs_attr_get(&args);
+	if (error) {
+		dbprintf(_("failed to get attr %s on inode %llu: %s\n"),
+			args.name, (unsigned long long)iocur_top->ino,
+			strerror(error));
+		goto out;
+	}
+
+	if (fsprop)
+		print_fsprop(&args);
+	else
+		printf("%.*s\n", args.valuelen, (char *)args.value);
+
+out:
+	if (args.dp)
+		libxfs_irele(args.dp);
+	if (args.value)
+		free(args.value);
+	if (free_name)
 		free((void *)args.name);
 	return 0;
 }
diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8
index 9f6fea5748d4..f0865b2df4ec 100644
--- a/man/man8/xfs_db.8
+++ b/man/man8/xfs_db.8
@@ -184,7 +184,35 @@ Displays the length, free block count, per-AG reservation size, and per-AG
 reservation usage for a given AG.
 If no argument is given, display information for all AGs.
 .TP
-.BI "attr_remove [\-p|\-r|\-u|\-s] [\-n] [\-N " namefile "|" name "] "
+.BI "attr_get [\-p|\-r|\-u|\-s|\-Z] [\-N " namefile "|" name "] "
+Print the value of the specified extended attribute from the current file.
+.RS 1.0i
+.TP 0.4i
+.B \-p
+Sets the attribute in the parent namespace.
+Only one namespace option can be specified.
+.TP
+.B \-r
+Sets the attribute in the root namespace.
+Only one namespace option can be specified.
+.TP
+.B \-u
+Sets the attribute in the user namespace.
+Only one namespace option can be specified.
+.TP
+.B \-s
+Sets the attribute in the secure namespace.
+Only one namespace option can be specified.
+.TP
+.B \-Z
+Sets a filesystem property in the root namespace.
+Only one namespace option can be specified.
+.TP
+.B \-N
+Read the name from this file.
+.RE
+.TP
+.BI "attr_remove [\-p|\-r|\-u|\-s|\-Z] [\-n] [\-N " namefile "|" name "] "
 Remove the specified extended attribute from the current file.
 .RS 1.0i
 .TP 0.4i
@@ -204,6 +232,10 @@ Only one namespace option can be specified.
 Sets the attribute in the secure namespace.
 Only one namespace option can be specified.
 .TP
+.B \-Z
+Sets a filesystem property in the root namespace.
+Only one namespace option can be specified.
+.TP
 .B \-N
 Read the name from this file.
 .TP
@@ -211,7 +243,7 @@ Read the name from this file.
 Do not enable 'noattr2' mode on V4 filesystems.
 .RE
 .TP
-.BI "attr_set [\-p\-r|\-u|\-s] [\-n] [\-R|\-C] [\-v " valuelen "|\-V " valuefile "] [\-N " namefile "|" name "] "
+.BI "attr_set [\-p\-r|\-u|\-s|\-Z] [\-n] [\-R|\-C] [\-v " valuelen "|\-V " valuefile "] [\-N " namefile "|" name "] [" value "]"
 Sets an extended attribute on the current file with the given name.
 .RS 1.0i
 .TP 0.4i
@@ -231,6 +263,10 @@ Only one namespace option can be specified.
 Sets the attribute in the secure namespace.
 Only one namespace option can be specified.
 .TP
+.B \-Z
+Sets a filesystem property in the root namespace.
+Only one namespace option can be specified.
+.TP
 .B \-N
 Read the name from this file.
 .TP


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

* [PATCH 4/7] libxfs: hoist listxattr from xfs_repair
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
                     ` (2 preceding siblings ...)
  2024-07-30  3:20   ` [PATCH 3/7] xfs_db: improve getting and setting extended attributes Darrick J. Wong
@ 2024-07-30  3:20   ` Darrick J. Wong
  2024-07-30 21:38     ` Christoph Hellwig
  2024-07-30  3:21   ` [PATCH 5/7] libxfs: pass a transaction context through listxattr Darrick J. Wong
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:20 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Hoist the listxattr code from xfs_repair so that we can use it in
xfs_db.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 libxfs/Makefile    |    2 ++
 libxfs/listxattr.c |    2 +-
 libxfs/listxattr.h |    6 +++---
 repair/Makefile    |    2 --
 repair/pptr.c      |    2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)
 rename repair/listxattr.c => libxfs/listxattr.c (99%)
 rename repair/listxattr.h => libxfs/listxattr.h (81%)


diff --git a/libxfs/Makefile b/libxfs/Makefile
index 4e8f9a135818..2f2791cae587 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -23,6 +23,7 @@ HFILES = \
 	defer_item.h \
 	libxfs_io.h \
 	libxfs_api_defs.h \
+	listxattr.h \
 	init.h \
 	libxfs_priv.h \
 	linux-err.h \
@@ -69,6 +70,7 @@ CFILES = buf_mem.c \
 	defer_item.c \
 	init.c \
 	kmem.c \
+	listxattr.c \
 	logitem.c \
 	rdwr.c \
 	topology.c \
diff --git a/repair/listxattr.c b/libxfs/listxattr.c
similarity index 99%
rename from repair/listxattr.c
rename to libxfs/listxattr.c
index 2af77b7b2195..bedaca678439 100644
--- a/repair/listxattr.c
+++ b/libxfs/listxattr.c
@@ -6,7 +6,7 @@
 #include "libxfs.h"
 #include "libxlog.h"
 #include "libfrog/bitmap.h"
-#include "repair/listxattr.h"
+#include "listxattr.h"
 
 /* Call a function for every entry in a shortform xattr structure. */
 STATIC int
diff --git a/repair/listxattr.h b/libxfs/listxattr.h
similarity index 81%
rename from repair/listxattr.h
rename to libxfs/listxattr.h
index 2d26fce0f323..cddd96af7c0c 100644
--- a/repair/listxattr.h
+++ b/libxfs/listxattr.h
@@ -3,8 +3,8 @@
  * Copyright (c) 2022-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#ifndef __REPAIR_LISTXATTR_H__
-#define __REPAIR_LISTXATTR_H__
+#ifndef __LIBXFS_LISTXATTR_H__
+#define __LIBXFS_LISTXATTR_H__
 
 typedef int (*xattr_walk_fn)(struct xfs_inode *ip, unsigned int attr_flags,
 		const unsigned char *name, unsigned int namelen,
@@ -12,4 +12,4 @@ typedef int (*xattr_walk_fn)(struct xfs_inode *ip, unsigned int attr_flags,
 
 int xattr_walk(struct xfs_inode *ip, xattr_walk_fn attr_fn, void *priv);
 
-#endif /* __REPAIR_LISTXATTR_H__ */
+#endif /* __LIBXFS_LISTXATTR_H__ */
diff --git a/repair/Makefile b/repair/Makefile
index e7445d53e918..a36a95e353a5 100644
--- a/repair/Makefile
+++ b/repair/Makefile
@@ -24,7 +24,6 @@ HFILES = \
 	err_protos.h \
 	globals.h \
 	incore.h \
-	listxattr.h \
 	pptr.h \
 	prefetch.h \
 	progress.h \
@@ -59,7 +58,6 @@ CFILES = \
 	incore_ext.c \
 	incore_ino.c \
 	init.c \
-	listxattr.c \
 	phase1.c \
 	phase2.c \
 	phase3.c \
diff --git a/repair/pptr.c b/repair/pptr.c
index 8ec6a51d2c3d..cc66e637217f 100644
--- a/repair/pptr.c
+++ b/repair/pptr.c
@@ -11,7 +11,7 @@
 #include "repair/globals.h"
 #include "repair/err_protos.h"
 #include "repair/slab.h"
-#include "repair/listxattr.h"
+#include "libxfs/listxattr.h"
 #include "repair/threads.h"
 #include "repair/incore.h"
 #include "repair/pptr.h"


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

* [PATCH 5/7] libxfs: pass a transaction context through listxattr
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
                     ` (3 preceding siblings ...)
  2024-07-30  3:20   ` [PATCH 4/7] libxfs: hoist listxattr from xfs_repair Darrick J. Wong
@ 2024-07-30  3:21   ` Darrick J. Wong
  2024-07-30 21:38     ` Christoph Hellwig
  2024-07-30  3:21   ` [PATCH 6/7] xfs_db: add a command to list xattrs Darrick J. Wong
  2024-07-30  3:21   ` [PATCH 7/7] xfs_property: add a new tool to administer fs properties Darrick J. Wong
  6 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:21 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Pass a transaction context so that a new caller can walk the attr names
and query the values all in one go without deadlocking on nested buffer
access.

While we're at it, make the existing xfs_repair callers try to use
empty transactions so that we don't deadlock on cycles in the xattr
structure.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 libxfs/listxattr.c |   40 +++++++++++++++++++++++-----------------
 libxfs/listxattr.h |    6 ++++--
 repair/pptr.c      |    7 ++++++-
 3 files changed, 33 insertions(+), 20 deletions(-)


diff --git a/libxfs/listxattr.c b/libxfs/listxattr.c
index bedaca678439..34205682f022 100644
--- a/libxfs/listxattr.c
+++ b/libxfs/listxattr.c
@@ -11,6 +11,7 @@
 /* Call a function for every entry in a shortform xattr structure. */
 STATIC int
 xattr_walk_sf(
+	struct xfs_trans		*tp,
 	struct xfs_inode		*ip,
 	xattr_walk_fn			attr_fn,
 	void				*priv)
@@ -22,7 +23,7 @@ xattr_walk_sf(
 
 	sfe = libxfs_attr_sf_firstentry(hdr);
 	for (i = 0; i < hdr->count; i++) {
-		error = attr_fn(ip, sfe->flags, sfe->nameval, sfe->namelen,
+		error = attr_fn(tp, ip, sfe->flags, sfe->nameval, sfe->namelen,
 				&sfe->nameval[sfe->namelen], sfe->valuelen,
 				priv);
 		if (error)
@@ -37,6 +38,7 @@ xattr_walk_sf(
 /* Call a function for every entry in this xattr leaf block. */
 STATIC int
 xattr_walk_leaf_entries(
+	struct xfs_trans		*tp,
 	struct xfs_inode		*ip,
 	xattr_walk_fn			attr_fn,
 	struct xfs_buf			*bp,
@@ -75,7 +77,7 @@ xattr_walk_leaf_entries(
 			valuelen = be32_to_cpu(name_rmt->valuelen);
 		}
 
-		error = attr_fn(ip, entry->flags, name, namelen, value,
+		error = attr_fn(tp, ip, entry->flags, name, namelen, value,
 				valuelen, priv);
 		if (error)
 			return error;
@@ -91,6 +93,7 @@ xattr_walk_leaf_entries(
  */
 STATIC int
 xattr_walk_leaf(
+	struct xfs_trans		*tp,
 	struct xfs_inode		*ip,
 	xattr_walk_fn			attr_fn,
 	void				*priv)
@@ -98,18 +101,19 @@ xattr_walk_leaf(
 	struct xfs_buf			*leaf_bp;
 	int				error;
 
-	error = -libxfs_attr3_leaf_read(NULL, ip, ip->i_ino, 0, &leaf_bp);
+	error = -libxfs_attr3_leaf_read(tp, ip, ip->i_ino, 0, &leaf_bp);
 	if (error)
 		return error;
 
-	error = xattr_walk_leaf_entries(ip, attr_fn, leaf_bp, priv);
-	libxfs_trans_brelse(NULL, leaf_bp);
+	error = xattr_walk_leaf_entries(tp, ip, attr_fn, leaf_bp, priv);
+	libxfs_trans_brelse(tp, leaf_bp);
 	return error;
 }
 
 /* Find the leftmost leaf in the xattr dabtree. */
 STATIC int
 xattr_walk_find_leftmost_leaf(
+	struct xfs_trans		*tp,
 	struct xfs_inode		*ip,
 	struct bitmap			*seen_blocks,
 	struct xfs_buf			**leaf_bpp)
@@ -127,7 +131,7 @@ xattr_walk_find_leftmost_leaf(
 	for (;;) {
 		uint16_t		magic;
 
-		error = -libxfs_da3_node_read(NULL, ip, blkno, &bp,
+		error = -libxfs_da3_node_read(tp, ip, blkno, &bp,
 				XFS_ATTR_FORK);
 		if (error)
 			return error;
@@ -164,7 +168,7 @@ xattr_walk_find_leftmost_leaf(
 		/* Find the next level towards the leaves of the dabtree. */
 		btree = nodehdr.btree;
 		blkno = be32_to_cpu(btree->before);
-		libxfs_trans_brelse(NULL, bp);
+		libxfs_trans_brelse(tp, bp);
 
 		/* Make sure we haven't seen this new block already. */
 		if (bitmap_test(seen_blocks, blkno, 1))
@@ -184,13 +188,14 @@ xattr_walk_find_leftmost_leaf(
 	return 0;
 
 out_buf:
-	libxfs_trans_brelse(NULL, bp);
+	libxfs_trans_brelse(tp, bp);
 	return error;
 }
 
 /* Call a function for every entry in a node-format xattr structure. */
 STATIC int
 xattr_walk_node(
+	struct xfs_trans		*tp,
 	struct xfs_inode		*ip,
 	xattr_walk_fn			attr_fn,
 	void				*priv)
@@ -204,12 +209,12 @@ xattr_walk_node(
 
 	bitmap_alloc(&seen_blocks);
 
-	error = xattr_walk_find_leftmost_leaf(ip, seen_blocks, &leaf_bp);
+	error = xattr_walk_find_leftmost_leaf(tp, ip, seen_blocks, &leaf_bp);
 	if (error)
 		goto out_bitmap;
 
 	for (;;) {
-		error = xattr_walk_leaf_entries(ip, attr_fn, leaf_bp,
+		error = xattr_walk_leaf_entries(tp, ip, attr_fn, leaf_bp,
 				priv);
 		if (error)
 			goto out_leaf;
@@ -220,13 +225,13 @@ xattr_walk_node(
 		if (leafhdr.forw == 0)
 			goto out_leaf;
 
-		libxfs_trans_brelse(NULL, leaf_bp);
+		libxfs_trans_brelse(tp, leaf_bp);
 
 		/* Make sure we haven't seen this new leaf already. */
 		if (bitmap_test(seen_blocks, leafhdr.forw, 1))
 			goto out_bitmap;
 
-		error = -libxfs_attr3_leaf_read(NULL, ip, ip->i_ino,
+		error = -libxfs_attr3_leaf_read(tp, ip, ip->i_ino,
 				leafhdr.forw, &leaf_bp);
 		if (error)
 			goto out_bitmap;
@@ -238,7 +243,7 @@ xattr_walk_node(
 	}
 
 out_leaf:
-	libxfs_trans_brelse(NULL, leaf_bp);
+	libxfs_trans_brelse(tp, leaf_bp);
 out_bitmap:
 	bitmap_free(&seen_blocks);
 	return error;
@@ -247,6 +252,7 @@ xattr_walk_node(
 /* Call a function for every extended attribute in a file. */
 int
 xattr_walk(
+	struct xfs_trans	*tp,
 	struct xfs_inode	*ip,
 	xattr_walk_fn		attr_fn,
 	void			*priv)
@@ -257,15 +263,15 @@ xattr_walk(
 		return 0;
 
 	if (ip->i_af.if_format == XFS_DINODE_FMT_LOCAL)
-		return xattr_walk_sf(ip, attr_fn, priv);
+		return xattr_walk_sf(tp, ip, attr_fn, priv);
 
 	/* attr functions require that the attr fork is loaded */
-	error = -libxfs_iread_extents(NULL, ip, XFS_ATTR_FORK);
+	error = -libxfs_iread_extents(tp, ip, XFS_ATTR_FORK);
 	if (error)
 		return error;
 
 	if (libxfs_attr_is_leaf(ip))
-		return xattr_walk_leaf(ip, attr_fn, priv);
+		return xattr_walk_leaf(tp, ip, attr_fn, priv);
 
-	return xattr_walk_node(ip, attr_fn, priv);
+	return xattr_walk_node(tp, ip, attr_fn, priv);
 }
diff --git a/libxfs/listxattr.h b/libxfs/listxattr.h
index cddd96af7c0c..933e0f529ec4 100644
--- a/libxfs/listxattr.h
+++ b/libxfs/listxattr.h
@@ -6,10 +6,12 @@
 #ifndef __LIBXFS_LISTXATTR_H__
 #define __LIBXFS_LISTXATTR_H__
 
-typedef int (*xattr_walk_fn)(struct xfs_inode *ip, unsigned int attr_flags,
+typedef int (*xattr_walk_fn)(struct xfs_trans *tp, struct xfs_inode *ip,
+		unsigned int attr_flags,
 		const unsigned char *name, unsigned int namelen,
 		const void *value, unsigned int valuelen, void *priv);
 
-int xattr_walk(struct xfs_inode *ip, xattr_walk_fn attr_fn, void *priv);
+int xattr_walk(struct xfs_trans *tp, struct xfs_inode *ip,
+		xattr_walk_fn attr_fn, void *priv);
 
 #endif /* __LIBXFS_LISTXATTR_H__ */
diff --git a/repair/pptr.c b/repair/pptr.c
index cc66e637217f..ee29e47a87bd 100644
--- a/repair/pptr.c
+++ b/repair/pptr.c
@@ -593,6 +593,7 @@ store_file_pptr_name(
 /* Decide if this is a directory parent pointer and stash it if so. */
 static int
 examine_xattr(
+	struct xfs_trans	*tp,
 	struct xfs_inode	*ip,
 	unsigned int		attr_flags,
 	const unsigned char	*name,
@@ -1205,6 +1206,7 @@ check_file_parent_ptrs(
 	struct xfs_inode	*ip,
 	struct file_scan	*fscan)
 {
+	struct xfs_trans	*tp = NULL;
 	int			error;
 
 	error = -init_slab(&fscan->file_pptr_recs, sizeof(struct file_pptr));
@@ -1215,7 +1217,10 @@ check_file_parent_ptrs(
 	fscan->have_garbage = false;
 	fscan->nr_file_pptrs = 0;
 
-	error = xattr_walk(ip, examine_xattr, fscan);
+	libxfs_trans_alloc_empty(ip->i_mount, &tp);
+	error = xattr_walk(tp, ip, examine_xattr, fscan);
+	if (tp)
+		libxfs_trans_cancel(tp);
 	if (error && !no_modify)
 		do_error(_("ino %llu parent pointer scan failed: %s\n"),
 				(unsigned long long)ip->i_ino,


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

* [PATCH 6/7] xfs_db: add a command to list xattrs
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
                     ` (4 preceding siblings ...)
  2024-07-30  3:21   ` [PATCH 5/7] libxfs: pass a transaction context through listxattr Darrick J. Wong
@ 2024-07-30  3:21   ` Darrick J. Wong
  2024-07-30 21:39     ` Christoph Hellwig
  2024-07-30  3:21   ` [PATCH 7/7] xfs_property: add a new tool to administer fs properties Darrick J. Wong
  6 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:21 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Add a command to list extended attributes from xfs_db.  We'll need this
later to manage the fs properties when unmounted.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 db/attrset.c      |  201 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/xfs_db.8 |   28 +++++++
 2 files changed, 229 insertions(+)


diff --git a/db/attrset.c b/db/attrset.c
index 4e7cca450322..9a7074069e27 100644
--- a/db/attrset.c
+++ b/db/attrset.c
@@ -18,13 +18,21 @@
 #include "malloc.h"
 #include <sys/xattr.h>
 #include "libfrog/fsproperties.h"
+#include "libxfs/listxattr.h"
 
+static int		attr_list_f(int argc, char **argv);
 static int		attr_get_f(int argc, char **argv);
 static int		attr_set_f(int argc, char **argv);
 static int		attr_remove_f(int argc, char **argv);
+
+static void		attrlist_help(void);
 static void		attrget_help(void);
 static void		attrset_help(void);
 
+static const cmdinfo_t	attr_list_cmd =
+	{ "attr_list", "alist", attr_list_f, 0, -1, 0,
+	  N_("[-r|-s|-u|-p|-Z] [-v]"),
+	  N_("list attributes on the current inode"), attrlist_help };
 static const cmdinfo_t	attr_get_cmd =
 	{ "attr_get", "aget", attr_get_f, 1, -1, 0,
 	  N_("[-r|-s|-u|-p|-Z] name"),
@@ -38,6 +46,24 @@ static const cmdinfo_t	attr_remove_cmd =
 	  N_("[-r|-s|-u|-p|-Z] [-n] name"),
 	  N_("remove the named attribute from the current inode"), attrset_help };
 
+static void
+attrlist_help(void)
+{
+	dbprintf(_(
+"\n"
+" The attr_list command provide interfaces for listing all extended attributes\n"
+" attached to an inode.\n"
+" There are 4 namespace flags:\n"
+"  -r -- 'root'\n"
+"  -u -- 'user'		(default)\n"
+"  -s -- 'secure'\n"
+"  -p -- 'parent'\n"
+"  -Z -- fs property\n"
+"\n"
+"  -v -- print the value of the attributes\n"
+"\n"));
+}
+
 static void
 attrget_help(void)
 {
@@ -88,6 +114,7 @@ attrset_init(void)
 	if (!expert_mode)
 		return;
 
+	add_command(&attr_list_cmd);
 	add_command(&attr_get_cmd);
 	add_command(&attr_set_cmd);
 	add_command(&attr_remove_cmd);
@@ -650,3 +677,177 @@ attr_get_f(
 		free((void *)args.name);
 	return 0;
 }
+
+struct attrlist_ctx {
+	unsigned int		attr_filter;
+	bool			print_values;
+	bool			fsprop;
+};
+
+static int
+attrlist_print(
+	struct xfs_trans	*tp,
+	struct xfs_inode	*ip,
+	unsigned int		attr_flags,
+	const unsigned char	*name,
+	unsigned int		namelen,
+	const void		*value,
+	unsigned int		valuelen,
+	void			*priv)
+{
+	struct attrlist_ctx	*ctx = priv;
+	struct xfs_da_args	args = {
+		.geo		= mp->m_attr_geo,
+		.whichfork	= XFS_ATTR_FORK,
+		.op_flags	= XFS_DA_OP_OKNOENT,
+		.dp		= ip,
+		.owner		= ip->i_ino,
+		.trans		= tp,
+		.attr_filter	= attr_flags & XFS_ATTR_NSP_ONDISK_MASK,
+		.name		= name,
+		.namelen	= namelen,
+	};
+	char			namebuf[MAXNAMELEN + 1];
+	const char		*print_name = namebuf;
+	int			error;
+
+	if ((attr_flags & XFS_ATTR_NSP_ONDISK_MASK) != ctx->attr_filter)
+		return 0;
+
+	/* Make sure the name is null terminated. */
+	memcpy(namebuf, name, namelen);
+	namebuf[MAXNAMELEN] = 0;
+
+	if (ctx->fsprop) {
+		const char	*p = attr_name_to_fsprop_name(namebuf);
+
+		if (!p)
+			return 0;
+
+		namelen -= (p - namebuf);
+		print_name = p;
+	}
+
+	if (!ctx->print_values) {
+		printf("%.*s\n", namelen, print_name);
+		return 0;
+	}
+
+	if (value) {
+		printf("%.*s=%.*s\n", namelen, print_name, valuelen,
+				(char *)value);
+		return 0;
+	}
+
+	libxfs_attr_sethash(&args);
+
+	/*
+	 * Look up attr value with a maximally long length and a null buffer
+	 * to return the value and the correct length.
+	 */
+	args.valuelen = XATTR_SIZE_MAX;
+	error = -libxfs_attr_get(&args);
+	if (error) {
+		dbprintf(_("failed to get attr %s on inode %llu: %s\n"),
+				args.name, (unsigned long long)iocur_top->ino,
+				strerror(error));
+		return error;
+	}
+
+	printf("%.*s=%.*s\n", namelen, print_name, args.valuelen,
+			(char *)args.value);
+	kfree(args.value);
+
+	return 0;
+}
+
+static int
+attr_list_f(
+	int			argc,
+	char			**argv)
+{
+	struct attrlist_ctx	ctx = { };
+	struct xfs_trans	*tp;
+	struct xfs_inode	*ip;
+	int			c;
+	int			error;
+
+	if (cur_typ == NULL) {
+		dbprintf(_("no current type\n"));
+		return 0;
+	}
+	if (cur_typ->typnm != TYP_INODE) {
+		dbprintf(_("current type is not inode\n"));
+		return 0;
+	}
+
+	while ((c = getopt(argc, argv, "ruspvZ")) != EOF) {
+		switch (c) {
+		/* namespaces */
+		case 'Z':
+			ctx.fsprop = true;
+			fallthrough;
+		case 'r':
+			ctx.attr_filter &= ~LIBXFS_ATTR_NS;
+			ctx.attr_filter |= LIBXFS_ATTR_ROOT;
+			break;
+		case 'u':
+			ctx.attr_filter &= ~LIBXFS_ATTR_NS;
+			break;
+		case 's':
+			ctx.attr_filter &= ~LIBXFS_ATTR_NS;
+			ctx.attr_filter |= LIBXFS_ATTR_SECURE;
+			break;
+		case 'p':
+			ctx.attr_filter &= ~LIBXFS_ATTR_NS;
+			ctx.attr_filter |= XFS_ATTR_PARENT;
+			break;
+
+		case 'v':
+			ctx.print_values = true;
+			break;
+		default:
+			dbprintf(_("bad option for attr_list command\n"));
+			return 0;
+		}
+	}
+
+	if (ctx.fsprop &&
+	    (ctx.attr_filter & LIBXFS_ATTR_NS) != LIBXFS_ATTR_ROOT) {
+		dbprintf(_("fs properties must be ATTR_ROOT\n"));
+		return false;
+	}
+
+	if (optind != argc) {
+		dbprintf(_("too many options for attr_list (no name needed)\n"));
+		return 0;
+	}
+
+	error = -libxfs_trans_alloc_empty(mp, &tp);
+	if (error) {
+		dbprintf(_("failed to allocate empty transaction\n"));
+		return 0;
+	}
+
+	error = -libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip);
+	if (error) {
+		dbprintf(_("failed to iget inode %llu: %s\n"),
+				(unsigned long long)iocur_top->ino,
+				strerror(error));
+		goto out_trans;
+	}
+
+	error = xattr_walk(tp, ip, attrlist_print, &ctx);
+	if (error) {
+		dbprintf(_("walking inode %llu xattrs: %s\n"),
+				(unsigned long long)iocur_top->ino,
+				strerror(error));
+		goto out_inode;
+	}
+
+out_inode:
+	libxfs_irele(ip);
+out_trans:
+	libxfs_trans_cancel(tp);
+	return 0;
+}
diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8
index f0865b2df4ec..291ec1c5827b 100644
--- a/man/man8/xfs_db.8
+++ b/man/man8/xfs_db.8
@@ -212,6 +212,34 @@ Only one namespace option can be specified.
 Read the name from this file.
 .RE
 .TP
+.BI "attr_list [\-p|\-r|\-u|\-s|\-Z] [\-v] "
+Lists the extended attributes of the current file.
+.RS 1.0i
+.TP 0.4i
+.B \-p
+Sets the attribute in the parent namespace.
+Only one namespace option can be specified.
+.TP
+.B \-r
+Sets the attribute in the root namespace.
+Only one namespace option can be specified.
+.TP
+.B \-u
+Sets the attribute in the user namespace.
+Only one namespace option can be specified.
+.TP
+.B \-s
+Sets the attribute in the secure namespace.
+Only one namespace option can be specified.
+.TP
+.B \-Z
+Sets a filesystem property in the root namespace.
+Only one namespace option can be specified.
+.TP
+.B \-v
+Print the extended attribute values too.
+.RE
+.TP
 .BI "attr_remove [\-p|\-r|\-u|\-s|\-Z] [\-n] [\-N " namefile "|" name "] "
 Remove the specified extended attribute from the current file.
 .RS 1.0i


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

* [PATCH 7/7] xfs_property: add a new tool to administer fs properties
  2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
                     ` (5 preceding siblings ...)
  2024-07-30  3:21   ` [PATCH 6/7] xfs_db: add a command to list xattrs Darrick J. Wong
@ 2024-07-30  3:21   ` Darrick J. Wong
  2024-07-30 21:43     ` Christoph Hellwig
  2024-08-02  0:25     ` Dave Chinner
  6 siblings, 2 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:21 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Create a tool to list, get, set, and remove filesystem properties.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 man/man8/xfs_property.8 |   52 ++++++++++++++++++++++++++++++++
 spaceman/Makefile       |    3 +-
 spaceman/xfs_property   |   77 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 131 insertions(+), 1 deletion(-)
 create mode 100644 man/man8/xfs_property.8
 create mode 100755 spaceman/xfs_property


diff --git a/man/man8/xfs_property.8 b/man/man8/xfs_property.8
new file mode 100644
index 000000000000..63245331bd86
--- /dev/null
+++ b/man/man8/xfs_property.8
@@ -0,0 +1,52 @@
+.TH xfs_property 8
+.SH NAME
+xfs_property \- examine and edit properties about an XFS filesystem
+.SH SYNOPSIS
+.B xfs_property
+.I target
+.B get
+.IR name ...
+.br
+.B xfs_property
+.I target
+.B list [ \-v ]
+.br
+.B xfs_property
+.I target
+.B set
+.IR name=value ...
+.br
+.B xfs_property
+.I target
+.B remove
+.IR name ...
+.br
+.B xfs_property \-V
+.SH DESCRIPTION
+.B xfs_property
+retrieves, lists, sets, or removes properties of an XFS filesystem.
+Filesystem properties are root-controlled attributes set on the root directory
+of the filesystem to enable the system administrator to coordinate with
+userspace programs.
+
+.SH COMMANDS
+.TP
+.B get
+.IR name ...
+Prints the values of the given filesystem properties.
+.TP
+.B list
+Lists the names of all filesystem properties.
+If the
+.B -v
+flag is specified, prints the values as well.
+.TP
+.B set
+.IR name = value ...
+Sets the given filesystem properties to the specified values and prints what
+was set.
+.TP
+.B
+remove
+.IR name ...
+Unsets the given filesystem properties.
diff --git a/spaceman/Makefile b/spaceman/Makefile
index 2688b37c770d..e914b921de8b 100644
--- a/spaceman/Makefile
+++ b/spaceman/Makefile
@@ -16,7 +16,7 @@ CFILES = \
 	init.c \
 	prealloc.c \
 	trim.c
-LSRCFILES = xfs_info.sh
+LSRCFILES = xfs_info.sh xfs_property
 
 LLDLIBS = $(LIBHANDLE) $(LIBXCMD) $(LIBFROG)
 LTDEPENDENCIES = $(LIBHANDLE) $(LIBXCMD) $(LIBFROG)
@@ -42,6 +42,7 @@ install: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 	$(INSTALL) -m 755 xfs_info.sh $(PKG_SBIN_DIR)/xfs_info
+	$(INSTALL) -m 755 xfs_property $(PKG_SBIN_DIR)/xfs_property
 install-dev:
 
 -include .dep
diff --git a/spaceman/xfs_property b/spaceman/xfs_property
new file mode 100755
index 000000000000..57185faa38db
--- /dev/null
+++ b/spaceman/xfs_property
@@ -0,0 +1,77 @@
+#!/bin/bash -f
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2024 Oracle.  All Rights Reserved.
+# Author: Darrick J. Wong <djwong@kernel.org>
+#
+
+OPTS=""
+USAGE="Usage: xfs_property [-V] [mountpoint|device|file] [list [-v]|get name...|set name=value...|remove name...]"
+
+# Try to find a loop device associated with a file.  We only want to return
+# one loopdev (multiple loop devices can attach to a single file) so we grab
+# the last line and return it if it's actually a block device.
+try_find_loop_dev_for_file() {
+	local x="$(losetup -O NAME -j "$1" 2> /dev/null | tail -n 1)"
+	test -b "${x}" && echo "${x}"
+}
+
+while getopts "V" c
+do
+	case $c in
+	V)	xfs_spaceman -p xfs_info -V
+		status=$?
+		exit ${status}
+		;;
+	*)	echo "${USAGE}" 1>&2
+		exit 2
+		;;
+	esac
+done
+set -- extra "$@"
+shift $OPTIND
+
+if [ $# -lt 2 ]; then
+	echo "${USAGE}" 1>&2
+	exit 2
+fi
+
+target="$1"
+shift
+subcommand="$1"
+shift
+
+db_args=()
+spaceman_args=()
+
+case "$subcommand" in
+"list")
+	vparam=
+	if [ $# -eq 1 ] && [ "$1" = "-v" ]; then
+		vparam=" -v"
+	fi
+	db_args+=('-c' "attr_list -Z${vparam}")
+	spaceman_args+=('-c' "listfsprops${vparam}")
+	;;
+"get"|"remove"|"set")
+	for arg in "$@"; do
+		db_args+=('-c' "attr_${subcommand} -Z ${arg/=/ }")
+		spaceman_args+=('-c' "${subcommand}fsprops ${arg}")
+	done
+	;;
+*)
+	echo "${USAGE}" 1>&2
+	exit 2
+esac
+
+# See if we can map the arg to a loop device
+loopdev="$(try_find_loop_dev_for_file "${target}")"
+test -n "${loopdev}" && target="${loopdev}"
+
+# If we find a mountpoint for the device, do a live query; otherwise try
+# reading the fs with xfs_db.
+if mountpt="$(findmnt -t xfs -f -n -o TARGET "${target}" 2> /dev/null)"; then
+	exec xfs_spaceman -p xfs_property "${spaceman_args[@]}" "${mountpt}"
+else
+	exec xfs_db -p xfs_property -x -c 'path /' "${db_args[@]}" "${target}"
+fi


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

* [PATCH 1/3] libfrog: define a self_healing filesystem property
  2024-07-30  3:19 ` [PATCHSET v30.9 2/3] xfs_scrub: control of autonomous self healing Darrick J. Wong
@ 2024-07-30  3:21   ` Darrick J. Wong
  2024-07-30 21:56     ` Christoph Hellwig
  2024-07-30  3:22   ` [PATCH 2/3] xfs_scrub: allow sysadmin to control background scrubs Darrick J. Wong
  2024-07-30  3:22   ` [PATCH 3/3] mkfs: set self_healing property Darrick J. Wong
  2 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:21 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 libfrog/fsproperties.c |   38 ++++++++++++++++++++++++++++++++++++++
 libfrog/fsproperties.h |   13 +++++++++++++
 2 files changed, 51 insertions(+)


diff --git a/libfrog/fsproperties.c b/libfrog/fsproperties.c
index c317d15c1de0..4ccd0edd8453 100644
--- a/libfrog/fsproperties.c
+++ b/libfrog/fsproperties.c
@@ -29,11 +29,49 @@ __fsprops_lookup(
 #define fsprops_lookup(values, value) \
 	__fsprops_lookup((values), ARRAY_SIZE(values), (value))
 
+/* Self-healing fs property */
+
+static const char *fsprop_self_healing_values[] = {
+	[FSPROP_SELFHEAL_UNSET]		= NULL,
+	[FSPROP_SELFHEAL_NONE]		= "none",
+	[FSPROP_SELFHEAL_CHECK]		= "check",
+	[FSPROP_SELFHEAL_OPTIMIZE]	= "optimize",
+	[FSPROP_SELFHEAL_REPAIR]	= "repair",
+};
+
+/* Convert the self_healing property enum to a string. */
+const char *
+fsprop_write_self_healing(
+	enum fsprop_self_healing	x)
+{
+	if (x <= FSPROP_SELFHEAL_UNSET ||
+	    x >= ARRAY_SIZE(fsprop_self_healing_values))
+		return NULL;
+	return fsprop_self_healing_values[x];
+}
+
+/*
+ * Turn a self_healing value string into an enumerated value, or _UNSET if it's
+ * not recognized.
+ */
+enum fsprop_self_healing
+fsprop_read_self_healing(
+	const char	*value)
+{
+	int ret = fsprops_lookup(fsprop_self_healing_values, value);
+	if (ret < 0)
+		return FSPROP_SELFHEAL_UNSET;
+	return ret;
+}
+
 /* Return true if a fs property name=value tuple is allowed. */
 bool
 fsprop_validate(
 	const char	*name,
 	const char	*value)
 {
+	if (!strcmp(name, FSPROP_SELF_HEALING_NAME))
+		return fsprops_lookup(fsprop_self_healing_values, value) >= 0;
+
 	return true;
 }
diff --git a/libfrog/fsproperties.h b/libfrog/fsproperties.h
index 6dee8259a437..7004d339715a 100644
--- a/libfrog/fsproperties.h
+++ b/libfrog/fsproperties.h
@@ -47,4 +47,17 @@ bool fsprop_validate(const char *name, const char *value);
 
 /* Specific Filesystem Properties */
 
+#define FSPROP_SELF_HEALING_NAME	"self_healing"
+
+enum fsprop_self_healing {
+	FSPROP_SELFHEAL_UNSET = 0,	/* do not set property */
+	FSPROP_SELFHEAL_NONE,		/* no background scrubs */
+	FSPROP_SELFHEAL_CHECK,		/* allow only background checking */
+	FSPROP_SELFHEAL_OPTIMIZE,	/* allow background optimization */
+	FSPROP_SELFHEAL_REPAIR,		/* allow background repair & optimization */
+};
+
+const char *fsprop_write_self_healing(enum fsprop_self_healing x);
+enum fsprop_self_healing fsprop_read_self_healing(const char *value);
+
 #endif /* __LIBFROG_FSPROPERTIES_H__ */


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

* [PATCH 2/3] xfs_scrub: allow sysadmin to control background scrubs
  2024-07-30  3:19 ` [PATCHSET v30.9 2/3] xfs_scrub: control of autonomous self healing Darrick J. Wong
  2024-07-30  3:21   ` [PATCH 1/3] libfrog: define a self_healing filesystem property Darrick J. Wong
@ 2024-07-30  3:22   ` Darrick J. Wong
  2024-07-30  3:22   ` [PATCH 3/3] mkfs: set self_healing property Darrick J. Wong
  2 siblings, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:22 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Define a "self_healing" filesystem property so that sysadmins can
indicate their preferences for background online fsck.  Add an extended
option to xfs_scrub so that it selects the operation mode from the self
healing fs property.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 man/man8/xfs_scrub.8 |   44 +++++++++++++++++++++++++++
 scrub/phase1.c       |   81 ++++++++++++++++++++++++++++++++++++++++++++++++++
 scrub/xfs_scrub.c    |   14 +++++++++
 scrub/xfs_scrub.h    |    7 ++++
 4 files changed, 146 insertions(+)


diff --git a/man/man8/xfs_scrub.8 b/man/man8/xfs_scrub.8
index 1fd122f2a242..1e017078019c 100644
--- a/man/man8/xfs_scrub.8
+++ b/man/man8/xfs_scrub.8
@@ -107,6 +107,14 @@ The
 supported are:
 .RS 1.0i
 .TP
+.B fsprops_advise
+Decide the operating mode from the value of the
+.I self_healing
+filesystem property.
+See the
+.B filesytem properties
+section for more details.
+.TP
 .BI fstrim_pct= percentage
 To constrain the amount of time spent on fstrim activities during phase 8,
 this program tries to balance estimated runtime against completeness of the
@@ -192,6 +200,42 @@ Scheduling a quotacheck for the next mount.
 .PP
 If corrupt metadata is successfully repaired, this program will log that
 a repair has succeeded instead of a corruption report.
+.SH FILESYSTEM PROPERTIES
+System administrators can convey their preferences for scrubbing of a
+particular filesystem by setting the filesystem property
+.B self_healing
+via the
+.B setfsprops
+subcommand of the
+.B xfs_spaceman
+on the filesystem.
+These preferences will be honored if the
+.B -o fsprops_advise
+option is specified.
+
+Recognized values for the
+.B self_healing
+property are:
+.RS
+.TP
+.I none
+Do not scan the filesystem at all.
+.TP
+.I check
+Scan and report corruption and opportunities for optimization, but do not
+change anything.
+.TP
+.I optimize
+Scan the filesystem and optimize where possible.
+Report corruptions, but do not fix them.
+.TP
+.I repair
+Scan the filesystem, fix corruptions, and optimize where possible.
+.RE
+
+If the property is not set, the default is
+.IR check .
+
 .SH EXIT CODE
 The exit code returned by
 .B xfs_scrub
diff --git a/scrub/phase1.c b/scrub/phase1.c
index 091b59e57e7b..5fa215a5bb79 100644
--- a/scrub/phase1.c
+++ b/scrub/phase1.c
@@ -28,6 +28,8 @@
 #include "repair.h"
 #include "libfrog/fsgeom.h"
 #include "xfs_errortag.h"
+#include "libfrog/fsprops.h"
+#include "libfrog/fsproperties.h"
 
 /* Phase 1: Find filesystem geometry (and clean up after) */
 
@@ -130,6 +132,77 @@ enable_force_repair(
 	return error;
 }
 
+#define MAX_SELFHEAL_LEN		128
+/*
+ * Decide the operating mode from filesystem properties.  No fs property or
+ * system errors means we only check.
+ */
+static void
+mode_from_fsprops(
+	struct scrub_ctx		*ctx)
+{
+	struct fsprops_handle		fph = { };
+	char				valuebuf[MAX_SELFHEAL_LEN + 1] = { 0 };
+	size_t				valuelen = MAX_SELFHEAL_LEN;
+	enum fsprop_self_healing	shval;
+	int				ret;
+
+	ret = fsprops_open_handle(&ctx->mnt, &ctx->fsinfo, &fph);
+	if (ret) {
+		ctx->mode = SCRUB_MODE_DRY_RUN;
+		goto summarize;
+	}
+
+	ret = fsprops_get(&fph, FSPROP_SELF_HEALING_NAME, valuebuf, &valuelen);
+	if (ret) {
+		ctx->mode = SCRUB_MODE_DRY_RUN;
+		goto summarize;
+	}
+
+	shval = fsprop_read_self_healing(valuebuf);
+	switch (shval) {
+	case FSPROP_SELFHEAL_NONE:
+		ctx->mode = SCRUB_MODE_NONE;
+		break;
+	case FSPROP_SELFHEAL_OPTIMIZE:
+		ctx->mode = SCRUB_MODE_PREEN;
+		break;
+	case FSPROP_SELFHEAL_REPAIR:
+		ctx->mode = SCRUB_MODE_REPAIR;
+		break;
+	case FSPROP_SELFHEAL_UNSET:
+		str_info(ctx, ctx->mntpoint,
+ _("Unknown self_healing directive \"%s\"."),
+				valuebuf);
+		fallthrough;
+	case FSPROP_SELFHEAL_CHECK:
+		ctx->mode = SCRUB_MODE_DRY_RUN;
+		break;
+	}
+
+	fsprops_free_handle(&fph);
+
+summarize:
+	switch (ctx->mode) {
+	case SCRUB_MODE_NONE:
+		str_info(ctx, ctx->mntpoint,
+ _("Disabling scrub per self_healing directive."));
+		break;
+	case SCRUB_MODE_DRY_RUN:
+		str_info(ctx, ctx->mntpoint,
+ _("Checking per self_healing directive."));
+		break;
+	case SCRUB_MODE_PREEN:
+		str_info(ctx, ctx->mntpoint,
+ _("Optimizing per self_healing directive."));
+		break;
+	case SCRUB_MODE_REPAIR:
+		str_info(ctx, ctx->mntpoint,
+ _("Checking and repairing per self_healing directive."));
+		break;
+	}
+}
+
 /*
  * Bind to the mountpoint, read the XFS geometry, bind to the block devices.
  * Anything we've already built will be cleaned up by scrub_cleanup.
@@ -206,6 +279,14 @@ _("Not an XFS filesystem."));
 		return error;
 	}
 
+	/*
+	 * If we've been instructed to decide the operating mode from the
+	 * fs properties set on the mount point, do that now before we start
+	 * downgrading based on actual fs/kernel capabilities.
+	 */
+	if (ctx->mode == SCRUB_MODE_NONE)
+		mode_from_fsprops(ctx);
+
 	/* Do we have kernel-assisted metadata scrubbing? */
 	if (!can_scrub_fs_metadata(ctx) || !can_scrub_inode(ctx) ||
 	    !can_scrub_bmap(ctx) || !can_scrub_dir(ctx) ||
diff --git a/scrub/xfs_scrub.c b/scrub/xfs_scrub.c
index f5b58de12812..a9d7e5ffe6d7 100644
--- a/scrub/xfs_scrub.c
+++ b/scrub/xfs_scrub.c
@@ -526,6 +526,10 @@ _("Scrub aborted after phase %d."),
 		if (ret)
 			break;
 
+		/* Did background scrub get canceled on us? */
+		if (ctx->mode == SCRUB_MODE_NONE)
+			break;
+
 		/* Too many errors? */
 		if (scrub_excessive_errors(ctx)) {
 			ret = ECANCELED;
@@ -630,12 +634,14 @@ report_outcome(
 enum o_opt_nums {
 	IWARN = 0,
 	FSTRIM_PCT,
+	FSPROPS_ADVISE,
 	O_MAX_OPTS,
 };
 
 static char *o_opts[] = {
 	[IWARN]			= "iwarn",
 	[FSTRIM_PCT]		= "fstrim_pct",
+	[FSPROPS_ADVISE]	= "fsprops_advise",
 	[O_MAX_OPTS]		= NULL,
 };
 
@@ -688,6 +694,14 @@ parse_o_opts(
 
 			ctx->fstrim_block_pct = dval / 100.0;
 			break;
+		case FSPROPS_ADVISE:
+			if (val) {
+				fprintf(stderr,
+ _("-o fsprops_advise does not take an argument\n"));
+				usage();
+			}
+			ctx->mode = SCRUB_MODE_NONE;
+			break;
 		default:
 			usage();
 			break;
diff --git a/scrub/xfs_scrub.h b/scrub/xfs_scrub.h
index 4d9a028921b5..582ec8e579e9 100644
--- a/scrub/xfs_scrub.h
+++ b/scrub/xfs_scrub.h
@@ -26,6 +26,13 @@ extern bool			use_force_rebuild;
 extern bool			info_is_warning;
 
 enum scrub_mode {
+	/*
+	 * Prior to phase 1, this means that xfs_scrub should read the
+	 * "self_healing" fs property from the mount and set the value
+	 * appropriate.  If it's still set after phase 1, this means we should
+	 * exit without doing anything.
+	 */
+	SCRUB_MODE_NONE,
 	SCRUB_MODE_DRY_RUN,
 	SCRUB_MODE_PREEN,
 	SCRUB_MODE_REPAIR,


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

* [PATCH 3/3] mkfs: set self_healing property
  2024-07-30  3:19 ` [PATCHSET v30.9 2/3] xfs_scrub: control of autonomous self healing Darrick J. Wong
  2024-07-30  3:21   ` [PATCH 1/3] libfrog: define a self_healing filesystem property Darrick J. Wong
  2024-07-30  3:22   ` [PATCH 2/3] xfs_scrub: allow sysadmin to control background scrubs Darrick J. Wong
@ 2024-07-30  3:22   ` Darrick J. Wong
  2 siblings, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:22 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Add a new mkfs options so that sysadmins can control the background
scrubbing behavior of filesystems from the start.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 man/man8/mkfs.xfs.8.in |    6 ++
 mkfs/lts_4.19.conf     |    1 
 mkfs/lts_5.10.conf     |    1 
 mkfs/lts_5.15.conf     |    1 
 mkfs/lts_5.4.conf      |    1 
 mkfs/lts_6.1.conf      |    1 
 mkfs/lts_6.6.conf      |    1 
 mkfs/xfs_mkfs.c        |  122 ++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 133 insertions(+), 1 deletion(-)


diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in
index d5a0783ac5d6..a66fd2a606ed 100644
--- a/man/man8/mkfs.xfs.8.in
+++ b/man/man8/mkfs.xfs.8.in
@@ -323,6 +323,12 @@ option set. When the option
 .B \-m crc=0
 is used, the reference count btree feature is not supported and reflink is
 disabled.
+.TP
+.BI self_healing= value
+Set the self_healing filesystem property to this value.
+See the
+.BI xfs_scrub (8)
+manual page for more information on this property.
 .RE
 .PP
 .PD 0
diff --git a/mkfs/lts_4.19.conf b/mkfs/lts_4.19.conf
index 9fa1f9378f32..291200a1ff23 100644
--- a/mkfs/lts_4.19.conf
+++ b/mkfs/lts_4.19.conf
@@ -8,6 +8,7 @@ finobt=1
 inobtcount=0
 reflink=0
 rmapbt=0
+self_healing=0
 
 [inode]
 sparse=1
diff --git a/mkfs/lts_5.10.conf b/mkfs/lts_5.10.conf
index d64bcdf8c46b..7c95dcf4c1ce 100644
--- a/mkfs/lts_5.10.conf
+++ b/mkfs/lts_5.10.conf
@@ -8,6 +8,7 @@ finobt=1
 inobtcount=0
 reflink=1
 rmapbt=0
+self_healing=0
 
 [inode]
 sparse=1
diff --git a/mkfs/lts_5.15.conf b/mkfs/lts_5.15.conf
index 775fd9ab91b8..8797078e406a 100644
--- a/mkfs/lts_5.15.conf
+++ b/mkfs/lts_5.15.conf
@@ -8,6 +8,7 @@ finobt=1
 inobtcount=1
 reflink=1
 rmapbt=0
+self_healing=0
 
 [inode]
 sparse=1
diff --git a/mkfs/lts_5.4.conf b/mkfs/lts_5.4.conf
index 6f43a6c6d469..c741b8260d90 100644
--- a/mkfs/lts_5.4.conf
+++ b/mkfs/lts_5.4.conf
@@ -8,6 +8,7 @@ finobt=1
 inobtcount=0
 reflink=1
 rmapbt=0
+self_healing=0
 
 [inode]
 sparse=1
diff --git a/mkfs/lts_6.1.conf b/mkfs/lts_6.1.conf
index a78a4f9e35dc..834facc1d5fb 100644
--- a/mkfs/lts_6.1.conf
+++ b/mkfs/lts_6.1.conf
@@ -8,6 +8,7 @@ finobt=1
 inobtcount=1
 reflink=1
 rmapbt=0
+self_healing=0
 
 [inode]
 sparse=1
diff --git a/mkfs/lts_6.6.conf b/mkfs/lts_6.6.conf
index 91a25bd8121f..10e965942e38 100644
--- a/mkfs/lts_6.6.conf
+++ b/mkfs/lts_6.6.conf
@@ -8,6 +8,7 @@ finobt=1
 inobtcount=1
 reflink=1
 rmapbt=1
+self_healing=0
 
 [inode]
 sparse=1
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
index 394a35771246..ea4e97725541 100644
--- a/mkfs/xfs_mkfs.c
+++ b/mkfs/xfs_mkfs.c
@@ -12,6 +12,7 @@
 #include "libfrog/convert.h"
 #include "libfrog/crc32cselftest.h"
 #include "libfrog/dahashselftest.h"
+#include "libfrog/fsproperties.h"
 #include "proto.h"
 #include <ini.h>
 
@@ -148,6 +149,7 @@ enum {
 	M_REFLINK,
 	M_INOBTCNT,
 	M_BIGTIME,
+	M_SELFHEAL,
 	M_MAX_OPTS,
 };
 
@@ -809,6 +811,7 @@ static struct opt_params mopts = {
 		[M_REFLINK] = "reflink",
 		[M_INOBTCNT] = "inobtcount",
 		[M_BIGTIME] = "bigtime",
+		[M_SELFHEAL] = "self_healing",
 		[M_MAX_OPTS] = NULL,
 	},
 	.subopt_params = {
@@ -852,6 +855,12 @@ static struct opt_params mopts = {
 		  .maxval = 1,
 		  .defaultval = 1,
 		},
+		{ .index = M_SELFHEAL,
+		  .conflicts = { { NULL, LAST_CONFLICT } },
+		  .minval = 0,
+		  .maxval = 1,
+		  .defaultval = 1,
+		},
 	},
 };
 
@@ -917,6 +926,8 @@ struct cli_params {
 	char	*cfgfile;
 	char	*protofile;
 
+	enum fsprop_self_healing self_healing;
+
 	/* parameters that depend on sector/block size being validated. */
 	char	*dsize;
 	char	*agsize;
@@ -1037,7 +1048,7 @@ usage( void )
 /* blocksize */		[-b size=num]\n\
 /* config file */	[-c options=xxx]\n\
 /* metadata */		[-m crc=0|1,finobt=0|1,uuid=xxx,rmapbt=0|1,reflink=0|1,\n\
-			    inobtcount=0|1,bigtime=0|1]\n\
+			    inobtcount=0|1,bigtime=0|1,self_healing=xxx]\n\
 /* data subvol */	[-d agcount=n,agsize=n,file,name=xxx,size=num,\n\
 			    (sunit=value,swidth=value|su=num,sw=num|noalign),\n\
 			    sectsize=num,concurrency=num]\n\
@@ -1858,6 +1869,20 @@ meta_opts_parser(
 	case M_BIGTIME:
 		cli->sb_feat.bigtime = getnum(value, opts, subopt);
 		break;
+	case M_SELFHEAL:
+		if (!value || value[0] == 0 || isdigit(value[0])) {
+			long long	ival = getnum(value, opts, subopt);
+
+			if (ival)
+				cli->self_healing = FSPROP_SELFHEAL_REPAIR;
+			else
+				cli->self_healing = FSPROP_SELFHEAL_NONE;
+		} else {
+			cli->self_healing = fsprop_read_self_healing(value);
+			if (cli->self_healing == FSPROP_SELFHEAL_UNSET)
+				illegal(value, "m self_heal");
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -2323,6 +2348,32 @@ _("Directory ftype field always enabled on CRC enabled filesystems\n"));
 			usage();
 		}
 
+		/*
+		 * Self-healing through online fsck relies heavily on back
+		 * reference metadata, so we really want to try to enable rmap
+		 * and parent pointers.
+		 */
+		if (cli->self_healing >= FSPROP_SELFHEAL_CHECK) {
+			if (!cli->sb_feat.rmapbt) {
+				if (cli_opt_set(&mopts, M_RMAPBT)) {
+					fprintf(stdout,
+_("self-healing=%s is less effective without reverse mapping\n"),
+						fsprop_write_self_healing(cli->self_healing));
+				} else {
+					cli->sb_feat.rmapbt = true;
+				}
+			}
+			if (!cli->sb_feat.parent_pointers) {
+				if (cli_opt_set(&nopts, N_PARENT)) {
+					fprintf(stdout,
+_("self-healing=%s is less effective without parent pointers\n"),
+						fsprop_write_self_healing(cli->self_healing));
+				} else {
+					cli->sb_feat.parent_pointers = true;
+				}
+			}
+		}
+
 	} else {	/* !crcs_enabled */
 		/*
 		 * The V4 filesystem format is deprecated in the upstream Linux
@@ -2406,6 +2457,14 @@ _("parent pointers not supported without CRC support\n"));
 			usage();
 		}
 		cli->sb_feat.parent_pointers = false;
+
+		if (cli->self_healing != FSPROP_SELFHEAL_UNSET &&
+		    cli_opt_set(&mopts, M_SELFHEAL)) {
+			fprintf(stderr,
+_("self-healing not supported without CRC support\n"));
+			usage();
+		}
+		cli->self_healing = FSPROP_SELFHEAL_UNSET;
 	}
 
 	if (!cli->sb_feat.finobt) {
@@ -4332,6 +4391,63 @@ cfgfile_parse(
 		cli->cfgfile);
 }
 
+static void
+set_self_healing(
+	struct xfs_mount	*mp,
+	struct cli_params	*cli)
+{
+	struct xfs_da_args	args = {
+		.geo		= mp->m_attr_geo,
+		.whichfork	= XFS_ATTR_FORK,
+		.op_flags	= XFS_DA_OP_OKNOENT,
+		.attr_filter	= LIBXFS_ATTR_ROOT,
+		.owner		= mp->m_sb.sb_rootino,
+	};
+	const char		*word;
+	char			*p;
+	int			error;
+
+	error = fsprop_name_to_attr_name(FSPROP_SELF_HEALING_NAME, &p);
+	if (error < 0) {
+		fprintf(stderr,
+ _("%s: error %d while allocating fs property name\n"),
+				progname, error);
+		exit(1);
+	}
+	args.namelen = error;
+	args.name = p;
+
+	word = fsprop_write_self_healing(cli->self_healing);
+	if (!word) {
+		fprintf(stderr,
+ _("%s: not sure what to do with self_healing value %u\n"),
+				progname, cli->self_healing);
+		exit(1);
+	}
+	args.value = (void *)word;
+	args.valuelen = strlen(word);
+
+	error = -libxfs_iget(mp, NULL, mp->m_sb.sb_rootino, 0, &args.dp);
+	if (error) {
+		fprintf(stderr,
+ _("%s: error %d while opening root directory\n"),
+				progname, error);
+		exit(1);
+	}
+
+	libxfs_attr_sethash(&args);
+
+	error = -libxfs_attr_set(&args, XFS_ATTRUPDATE_UPSERT, false);
+	if (error) {
+		fprintf(stderr,
+ _("%s: error %d while setting self_healing property\n"),
+				progname, error);
+		exit(1);
+	}
+
+	libxfs_irele(args.dp);
+}
+
 int
 main(
 	int			argc,
@@ -4361,6 +4477,7 @@ main(
 		.is_supported	= 1,
 		.data_concurrency = -1, /* auto detect non-mechanical storage */
 		.log_concurrency = -1, /* auto detect non-mechanical ddev */
+		.self_healing = FSPROP_SELFHEAL_UNSET,
 	};
 	struct mkfs_params	cfg = {};
 
@@ -4669,6 +4786,9 @@ main(
 	if (mp->m_sb.sb_agcount > 1)
 		rewrite_secondary_superblocks(mp);
 
+	if (cli.self_healing != FSPROP_SELFHEAL_UNSET)
+		set_self_healing(mp, &cli);
+
 	/*
 	 * Dump all inodes and buffers before marking us all done.
 	 * Need to drop references to inodes we still hold, first.


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

* [PATCH 1/3] misc: shift install targets
  2024-07-30  3:19 ` [PATCHSET v30.9 3/3] xfs_scrub: separate package for self healing Darrick J. Wong
@ 2024-07-30  3:22   ` Darrick J. Wong
  2024-07-30  3:22   ` [PATCH 2/3] xfs_scrub: use the self_healing fsproperty to select mode Darrick J. Wong
  2024-07-30  3:23   ` [PATCH 3/3] debian: create a new package for automatic self-healing Darrick J. Wong
  2 siblings, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:22 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Modify each Makefile so that "install-pkg" installs the main package
contents, and "install" just invokes "install-pkg".  We'll need this
indirection for the next patch where we add an install-selfheal target
to build the xfsprogs-self-healing package but will still want 'make
install' to install everything on a developer's workstation.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 Makefile           |    8 +++++---
 copy/Makefile      |    4 +++-
 db/Makefile        |    4 +++-
 debian/Makefile    |    4 +++-
 debian/rules       |    2 +-
 doc/Makefile       |    4 +++-
 estimate/Makefile  |    4 +++-
 fsck/Makefile      |    4 +++-
 fsr/Makefile       |    4 +++-
 growfs/Makefile    |    4 +++-
 include/Makefile   |    4 +++-
 io/Makefile        |    4 +++-
 libfrog/Makefile   |    2 +-
 libhandle/Makefile |    4 +++-
 libxcmd/Makefile   |    2 +-
 libxfs/Makefile    |    4 +++-
 libxlog/Makefile   |    2 +-
 logprint/Makefile  |    4 +++-
 m4/Makefile        |    2 +-
 man/Makefile       |    8 +++++---
 man/man2/Makefile  |    4 +++-
 man/man3/Makefile  |    4 +++-
 man/man5/Makefile  |    5 ++++-
 man/man8/Makefile  |    4 +++-
 mdrestore/Makefile |    4 +++-
 mkfs/Makefile      |    4 +++-
 po/Makefile        |    4 +++-
 quota/Makefile     |    4 +++-
 repair/Makefile    |    4 +++-
 rtcp/Makefile      |    4 +++-
 scrub/Makefile     |    4 +++-
 spaceman/Makefile  |    4 +++-
 32 files changed, 91 insertions(+), 36 deletions(-)


diff --git a/Makefile b/Makefile
index 4e768526c6fe..44b6c3501539 100644
--- a/Makefile
+++ b/Makefile
@@ -116,15 +116,17 @@ configure: configure.ac
 include/builddefs: configure
 	./configure $$LOCAL_CONFIGURE_OPTIONS
 
-install: $(addsuffix -install,$(SUBDIRS))
+install: install-pkg
+
+install-pkg: $(addsuffix -install-pkg,$(SUBDIRS))
 	$(INSTALL) -m 755 -d $(PKG_DOC_DIR)
 	$(INSTALL) -m 644 README $(PKG_DOC_DIR)
 
 install-dev: $(addsuffix -install-dev,$(SUBDIRS))
 
-%-install:
+%-install-pkg:
 	@echo "Installing $@"
-	$(Q)$(MAKE) $(MAKEOPTS) -C $* install
+	$(Q)$(MAKE) $(MAKEOPTS) -C $* install-pkg
 
 %-install-dev:
 	@echo "Installing $@"
diff --git a/copy/Makefile b/copy/Makefile
index 55160f848225..446d38bea576 100644
--- a/copy/Makefile
+++ b/copy/Makefile
@@ -18,7 +18,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
diff --git a/db/Makefile b/db/Makefile
index 83389376c36c..91e259044beb 100644
--- a/db/Makefile
+++ b/db/Makefile
@@ -81,7 +81,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 	$(INSTALL) -m 755 xfs_admin.sh $(PKG_SBIN_DIR)/xfs_admin
diff --git a/debian/Makefile b/debian/Makefile
index 2f9cd38c2ea6..f6a996e91871 100644
--- a/debian/Makefile
+++ b/debian/Makefile
@@ -15,7 +15,9 @@ default:
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 ifeq ($(PKG_DISTRIBUTION), debian)
 	$(INSTALL) -m 755 -d $(PKG_DOC_DIR)
 	$(INSTALL) -m 644 changelog $(PKG_DOC_DIR)/changelog.Debian
diff --git a/debian/rules b/debian/rules
index 69a79fc67405..e4eb2499e768 100755
--- a/debian/rules
+++ b/debian/rules
@@ -100,7 +100,7 @@ binary-arch: checkroot built
 	@echo "== dpkg-buildpackage: binary-arch" 1>&2
 	$(checkdir)
 	-rm -rf $(dirme) $(dirdev) $(dirdi)
-	$(pkgme)  $(MAKE) -C . install
+	$(pkgme)  $(MAKE) -C . install-pkg
 	$(pkgdev) $(MAKE) -C . install-dev
 	$(pkgdi)  $(MAKE) -C debian install-d-i
 	$(pkgme)  $(MAKE) dist
diff --git a/doc/Makefile b/doc/Makefile
index 83dfa38bedd1..ad6749b8d0be 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -16,7 +16,9 @@ CHANGES.gz:
 	@echo "    [ZIP]    $@"
 	$(Q)$(ZIP) --best -c < CHANGES > $@
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_DOC_DIR)
 	$(INSTALL) -m 644 CHANGES.gz CREDITS $(PKG_DOC_DIR)
 ifeq ($(PKG_DISTRIBUTION), debian)
diff --git a/estimate/Makefile b/estimate/Makefile
index 1080129b3a62..d5f8a6d81d65 100644
--- a/estimate/Makefile
+++ b/estimate/Makefile
@@ -12,7 +12,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
diff --git a/fsck/Makefile b/fsck/Makefile
index 5ca529f53e42..ccba7f0b6892 100644
--- a/fsck/Makefile
+++ b/fsck/Makefile
@@ -11,7 +11,9 @@ default: $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(INSTALL) -m 755 xfs_fsck.sh $(PKG_SBIN_DIR)/fsck.xfs
 install-dev:
diff --git a/fsr/Makefile b/fsr/Makefile
index d57f2de24c22..3ad9f6d824c6 100644
--- a/fsr/Makefile
+++ b/fsr/Makefile
@@ -15,7 +15,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
diff --git a/growfs/Makefile b/growfs/Makefile
index 2f4cc66a76f3..e0ab870bd6ba 100644
--- a/growfs/Makefile
+++ b/growfs/Makefile
@@ -23,7 +23,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
diff --git a/include/Makefile b/include/Makefile
index f7c40a5ce1a1..23727fccfdcd 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -57,7 +57,9 @@ install-headers: $(addsuffix -hdrs, $(DKHFILES) $(HFILES))
 %-hdrs:
 	$(Q)$(LN_S) -f $(CURDIR)/$* xfs/$*
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_INC_DIR)
 
 install-dev: install
diff --git a/io/Makefile b/io/Makefile
index 3192b813c740..d035420b555c 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -85,7 +85,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 xfs_bmap.sh $(PKG_SBIN_DIR)/xfs_bmap
diff --git a/libfrog/Makefile b/libfrog/Makefile
index acddc894ee93..5ebe36fb58c8 100644
--- a/libfrog/Makefile
+++ b/libfrog/Makefile
@@ -79,6 +79,6 @@ crc32table.h: gen_crc32table.c crc32defs.h
 
 include $(BUILDRULES)
 
-install install-dev: default
+install install-pkg install-dev: default
 
 -include .ltdep
diff --git a/libhandle/Makefile b/libhandle/Makefile
index f297a59e47f9..7cfd0fa4f27e 100644
--- a/libhandle/Makefile
+++ b/libhandle/Makefile
@@ -19,7 +19,9 @@ default: ltdepend $(LTLIBRARY)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL_LTLIB)
 
 install-dev: default
diff --git a/libxcmd/Makefile b/libxcmd/Makefile
index 70e54308c34b..afd5349c8af3 100644
--- a/libxcmd/Makefile
+++ b/libxcmd/Makefile
@@ -23,6 +23,6 @@ default: ltdepend $(LTLIBRARY)
 
 include $(BUILDRULES)
 
-install install-dev: default
+install install-pkg install-dev: default
 
 -include .ltdep
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 2f2791cae587..2c6b45953661 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -140,7 +140,9 @@ default: ltdepend $(LTLIBRARY)
 # set up include/xfs header directory
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_INC_DIR)
 
 install-headers: $(addsuffix -hdrs, $(PKGHFILES))
diff --git a/libxlog/Makefile b/libxlog/Makefile
index b0f5ef154133..3710729fe703 100644
--- a/libxlog/Makefile
+++ b/libxlog/Makefile
@@ -21,6 +21,6 @@ default: ltdepend $(LTLIBRARY)
 
 include $(BUILDRULES)
 
-install install-dev: default
+install install-pkg install-dev: default
 
 -include .ltdep
diff --git a/logprint/Makefile b/logprint/Makefile
index bbbed5d259af..5ec02539a7bb 100644
--- a/logprint/Makefile
+++ b/logprint/Makefile
@@ -21,7 +21,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
diff --git a/m4/Makefile b/m4/Makefile
index 84174c3d3e30..eda4c06f6864 100644
--- a/m4/Makefile
+++ b/m4/Makefile
@@ -33,7 +33,7 @@ default:
 
 include $(BUILDRULES)
 
-install install-dev install-lib: default
+install install-pkg install-dev install-lib: default
 
 realclean: distclean
 	rm -f $(CONFIGURE)
diff --git a/man/Makefile b/man/Makefile
index cd1aed6cf202..f62286e8339d 100644
--- a/man/Makefile
+++ b/man/Makefile
@@ -9,12 +9,14 @@ SUBDIRS = man2 man3 man5 man8
 
 default : $(SUBDIRS)
 
-install : $(addsuffix -install,$(SUBDIRS))
+install : install-pkg
+
+install-pkg : $(addsuffix -install-pkg,$(SUBDIRS))
 
 install-dev : $(addsuffix -install-dev,$(SUBDIRS))
 
-%-install:
-	$(Q)$(MAKE) $(MAKEOPTS) -C $* install
+%-install-pkg:
+	$(Q)$(MAKE) $(MAKEOPTS) -C $* install-pkg
 
 %-install-dev:
 	$(Q)$(MAKE) $(MAKEOPTS) -C $* install-dev
diff --git a/man/man2/Makefile b/man/man2/Makefile
index 8aecde3321b0..190ea18e7c6c 100644
--- a/man/man2/Makefile
+++ b/man/man2/Makefile
@@ -15,7 +15,9 @@ default : $(MAN_PAGES)
 
 include $(BUILDRULES)
 
-install :
+install : install-pkg
+
+install-pkg :
 
 install-dev : default
 	$(INSTALL) -m 755 -d $(MAN_DEST)
diff --git a/man/man3/Makefile b/man/man3/Makefile
index a7f607fcbad9..1553e2b2de82 100644
--- a/man/man3/Makefile
+++ b/man/man3/Makefile
@@ -15,7 +15,9 @@ default : $(MAN_PAGES)
 
 include $(BUILDRULES)
 
-install :
+install : install-pkg
+
+install-pkg :
 
 install-dev : default
 	$(INSTALL) -m 755 -d $(MAN_DEST)
diff --git a/man/man5/Makefile b/man/man5/Makefile
index fe0aef6f016b..1fcd3995036f 100644
--- a/man/man5/Makefile
+++ b/man/man5/Makefile
@@ -15,7 +15,10 @@ default : $(MAN_PAGES)
 
 include $(BUILDRULES)
 
-install : default
+install : install-pkg
+
+install-pkg : default
 	$(INSTALL) -m 755 -d $(MAN_DEST)
 	$(INSTALL_MAN)
+
 install-dev :
diff --git a/man/man8/Makefile b/man/man8/Makefile
index 5be76ab727a1..0b40a409a913 100644
--- a/man/man8/Makefile
+++ b/man/man8/Makefile
@@ -22,7 +22,9 @@ default : $(MAN_PAGES)
 
 include $(BUILDRULES)
 
-install : default
+install : install-pkg
+
+install-pkg : default
 	$(INSTALL) -m 755 -d $(MAN_DEST)
 	$(INSTALL_MAN)
 
diff --git a/mdrestore/Makefile b/mdrestore/Makefile
index 4a932efb8098..0d02fb383404 100644
--- a/mdrestore/Makefile
+++ b/mdrestore/Makefile
@@ -16,7 +16,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
diff --git a/mkfs/Makefile b/mkfs/Makefile
index a6173083e4c2..cf945aa10c25 100644
--- a/mkfs/Makefile
+++ b/mkfs/Makefile
@@ -27,7 +27,9 @@ default: depend $(LTCOMMAND) $(CFGFILES)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 	$(INSTALL) -m 755 -d $(MKFS_CFG_DIR)
diff --git a/po/Makefile b/po/Makefile
index 1d35f5191ba2..3cc0b4177c64 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -19,7 +19,9 @@ default: $(POTHEAD) $(LINGUAS:%=%.mo)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL_LINGUAS)
 
 install-dev install-lib:
diff --git a/quota/Makefile b/quota/Makefile
index da5a1489e468..01584635b3dd 100644
--- a/quota/Makefile
+++ b/quota/Makefile
@@ -23,7 +23,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
diff --git a/repair/Makefile b/repair/Makefile
index a36a95e353a5..096ae8c6a5b1 100644
--- a/repair/Makefile
+++ b/repair/Makefile
@@ -106,7 +106,9 @@ include $(BUILDRULES)
 #
 #CFLAGS += ...
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
diff --git a/rtcp/Makefile b/rtcp/Makefile
index 264b4f27b5fd..4adb58c4b783 100644
--- a/rtcp/Makefile
+++ b/rtcp/Makefile
@@ -16,7 +16,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
diff --git a/scrub/Makefile b/scrub/Makefile
index 885b43e9948d..653aafd171b5 100644
--- a/scrub/Makefile
+++ b/scrub/Makefile
@@ -138,7 +138,9 @@ phase5.o unicrash.o xfs.o: $(builddefs)
 
 include $(BUILDRULES)
 
-install: $(INSTALL_SCRUB)
+install: install-pkg
+
+install-pkg: $(INSTALL_SCRUB)
 
 %.service: %.service.in $(builddefs)
 	@echo "    [SED]    $@"
diff --git a/spaceman/Makefile b/spaceman/Makefile
index e914b921de8b..49fbc9290c02 100644
--- a/spaceman/Makefile
+++ b/spaceman/Makefile
@@ -38,7 +38,9 @@ default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
 
-install: default
+install: install-pkg
+
+install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 	$(INSTALL) -m 755 xfs_info.sh $(PKG_SBIN_DIR)/xfs_info


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

* [PATCH 2/3] xfs_scrub: use the self_healing fsproperty to select mode
  2024-07-30  3:19 ` [PATCHSET v30.9 3/3] xfs_scrub: separate package for self healing Darrick J. Wong
  2024-07-30  3:22   ` [PATCH 1/3] misc: shift install targets Darrick J. Wong
@ 2024-07-30  3:22   ` Darrick J. Wong
  2024-07-30  3:23   ` [PATCH 3/3] debian: create a new package for automatic self-healing Darrick J. Wong
  2 siblings, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:22 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Now that we can set properties on xfs filesystems, make the xfs_scrub
background service query the self_healing property to figure out which
mode (dry run, optimize, repair, none) it should use.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 scrub/Makefile                    |    3 +--
 scrub/xfs_scrub@.service.in       |    2 +-
 scrub/xfs_scrub_media@.service.in |    2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)


diff --git a/scrub/Makefile b/scrub/Makefile
index 653aafd171b5..b0022cb7f005 100644
--- a/scrub/Makefile
+++ b/scrub/Makefile
@@ -17,7 +17,7 @@ INSTALL_SCRUB = install-scrub
 XFS_SCRUB_ALL_PROG = xfs_scrub_all
 XFS_SCRUB_FAIL_PROG = xfs_scrub_fail
 XFS_SCRUB_ARGS = -p
-XFS_SCRUB_SERVICE_ARGS = -b
+XFS_SCRUB_SERVICE_ARGS = -b -o fsprops_advise
 ifeq ($(HAVE_SYSTEMD),yes)
 INSTALL_SCRUB += install-systemd
 SYSTEMD_SERVICES=\
@@ -146,7 +146,6 @@ install-pkg: $(INSTALL_SCRUB)
 	@echo "    [SED]    $@"
 	$(Q)$(SED) -e "s|@sbindir@|$(PKG_SBIN_DIR)|g" \
 		   -e "s|@scrub_service_args@|$(XFS_SCRUB_SERVICE_ARGS)|g" \
-		   -e "s|@scrub_args@|$(XFS_SCRUB_ARGS)|g" \
 		   -e "s|@pkg_libexec_dir@|$(PKG_LIBEXEC_DIR)|g" \
 		   -e "s|@pkg_state_dir@|$(PKG_STATE_DIR)|g" \
 		   -e "s|@media_scan_interval@|$(XFS_SCRUB_ALL_AUTO_MEDIA_SCAN_INTERVAL)|g" \
diff --git a/scrub/xfs_scrub@.service.in b/scrub/xfs_scrub@.service.in
index 5fa5f328200e..fb38319e95c1 100644
--- a/scrub/xfs_scrub@.service.in
+++ b/scrub/xfs_scrub@.service.in
@@ -22,7 +22,7 @@ RequiresMountsFor=%f
 [Service]
 Type=oneshot
 Environment=SERVICE_MODE=1
-ExecStart=@sbindir@/xfs_scrub @scrub_service_args@ @scrub_args@ -M /tmp/scrub/ %f
+ExecStart=@sbindir@/xfs_scrub @scrub_service_args@ -M /tmp/scrub/ %f
 SyslogIdentifier=%N
 
 # Run scrub with minimal CPU and IO priority so that nothing else will starve.
diff --git a/scrub/xfs_scrub_media@.service.in b/scrub/xfs_scrub_media@.service.in
index e670748ced51..98cd1ac44fbe 100644
--- a/scrub/xfs_scrub_media@.service.in
+++ b/scrub/xfs_scrub_media@.service.in
@@ -22,7 +22,7 @@ RequiresMountsFor=%f
 [Service]
 Type=oneshot
 Environment=SERVICE_MODE=1
-ExecStart=@sbindir@/xfs_scrub @scrub_service_args@ @scrub_args@ -M /tmp/scrub/ -x %f
+ExecStart=@sbindir@/xfs_scrub @scrub_service_args@ -M /tmp/scrub/ -x %f
 SyslogIdentifier=%N
 
 # Run scrub with minimal CPU and IO priority so that nothing else will starve.


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

* [PATCH 3/3] debian: create a new package for automatic self-healing
  2024-07-30  3:19 ` [PATCHSET v30.9 3/3] xfs_scrub: separate package for self healing Darrick J. Wong
  2024-07-30  3:22   ` [PATCH 1/3] misc: shift install targets Darrick J. Wong
  2024-07-30  3:22   ` [PATCH 2/3] xfs_scrub: use the self_healing fsproperty to select mode Darrick J. Wong
@ 2024-07-30  3:23   ` Darrick J. Wong
  2 siblings, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:23 UTC (permalink / raw)
  To: djwong, cem; +Cc: linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Create a new package for people who explicilty want self-healing turned
on by default for XFS.  This package is named xfsprogs-self-healing.

Note: This introduces a new "install-selfheal" target to install only
the files needed for enabling online fsck by default.  Other
distributions should take note of the new target if they choose to
create a package for enabling autonomous self healing.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 Makefile           |    8 +++++++-
 copy/Makefile      |    2 ++
 db/Makefile        |    2 ++
 debian/Makefile    |    2 ++
 debian/control     |    8 ++++++++
 debian/rules       |   13 +++++++++----
 doc/Makefile       |    3 +++
 estimate/Makefile  |    2 ++
 fsck/Makefile      |    3 +++
 fsr/Makefile       |    2 ++
 growfs/Makefile    |    2 ++
 include/Makefile   |    3 +++
 io/Makefile        |    2 ++
 libfrog/Makefile   |    2 ++
 libhandle/Makefile |    2 ++
 libxcmd/Makefile   |    2 ++
 libxfs/Makefile    |    3 +++
 libxlog/Makefile   |    2 ++
 logprint/Makefile  |    2 ++
 m4/Makefile        |    2 ++
 man/Makefile       |    2 ++
 mdrestore/Makefile |    2 ++
 mkfs/Makefile      |    2 ++
 po/Makefile        |    3 +++
 quota/Makefile     |    2 ++
 repair/Makefile    |    2 ++
 rtcp/Makefile      |    2 ++
 scrub/Makefile     |   12 ++++++++++--
 spaceman/Makefile  |    2 ++
 29 files changed, 89 insertions(+), 7 deletions(-)


diff --git a/Makefile b/Makefile
index 44b6c3501539..4bd792d191be 100644
--- a/Makefile
+++ b/Makefile
@@ -116,7 +116,7 @@ configure: configure.ac
 include/builddefs: configure
 	./configure $$LOCAL_CONFIGURE_OPTIONS
 
-install: install-pkg
+install: install-pkg install-selfheal
 
 install-pkg: $(addsuffix -install-pkg,$(SUBDIRS))
 	$(INSTALL) -m 755 -d $(PKG_DOC_DIR)
@@ -124,6 +124,8 @@ install-pkg: $(addsuffix -install-pkg,$(SUBDIRS))
 
 install-dev: $(addsuffix -install-dev,$(SUBDIRS))
 
+install-selfheal: $(addsuffix -install-selfheal,$(SUBDIRS))
+
 %-install-pkg:
 	@echo "Installing $@"
 	$(Q)$(MAKE) $(MAKEOPTS) -C $* install-pkg
@@ -132,6 +134,10 @@ install-dev: $(addsuffix -install-dev,$(SUBDIRS))
 	@echo "Installing $@"
 	$(Q)$(MAKE) $(MAKEOPTS) -C $* install-dev
 
+%-install-selfheal:
+	@echo "Installing $@"
+	$(Q)$(MAKE) $(MAKEOPTS) -C $* install-selfheal
+
 distclean: clean
 	$(Q)rm -f $(LDIRT)
 
diff --git a/copy/Makefile b/copy/Makefile
index 446d38bea576..3013dc2dca27 100644
--- a/copy/Makefile
+++ b/copy/Makefile
@@ -25,4 +25,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/db/Makefile b/db/Makefile
index 91e259044beb..839c51f03593 100644
--- a/db/Makefile
+++ b/db/Makefile
@@ -91,4 +91,6 @@ install-pkg: default
 	$(INSTALL) -m 755 xfs_metadump.sh $(PKG_SBIN_DIR)/xfs_metadump
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/debian/Makefile b/debian/Makefile
index f6a996e91871..104d7c5d76d9 100644
--- a/debian/Makefile
+++ b/debian/Makefile
@@ -36,3 +36,5 @@ ifeq ($(PKG_DISTRIBUTION), debian)
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(INSTALL) -m 755 $(BOOT_MKFS_BIN) $(PKG_SBIN_DIR)/mkfs.xfs
 endif
+
+install-selfheal: default
diff --git a/debian/control b/debian/control
index 31773e53a19a..aa7a920a7964 100644
--- a/debian/control
+++ b/debian/control
@@ -27,6 +27,14 @@ Description: Utilities for managing the XFS filesystem
  Refer to the documentation at https://xfs.wiki.kernel.org/
  for complete details.
 
+Package: xfsprogs-self-healing
+Depends: ${shlibs:Depends}, ${misc:Depends}, xfsprogs, systemd, udev
+Architecture: linux-any
+Description: Automatic self healing for the XFS filesystem
+ A set of background services for the XFS filesystem to make it
+ find and fix corruptions automatically.  These services are activated
+ automatically upon installation of this package.
+
 Package: xfslibs-dev
 Section: libdevel
 Depends: libc6-dev | libc-dev, uuid-dev, xfsprogs (>= 3.0.0), ${misc:Depends}
diff --git a/debian/rules b/debian/rules
index e4eb2499e768..c49aefd10e64 100755
--- a/debian/rules
+++ b/debian/rules
@@ -14,6 +14,7 @@ endif
 package = xfsprogs
 develop = xfslibs-dev
 bootpkg = xfsprogs-udeb
+healpkg = xfsprogs-self-healing
 
 DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
 DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
@@ -26,9 +27,11 @@ udebpkg = $(bootpkg)_$(version)_$(target).udeb
 dirme  = debian/$(package)
 dirdev = debian/$(develop)
 dirdi  = debian/$(bootpkg)
-pkgme  = DIST_ROOT=`pwd`/$(dirme);  export DIST_ROOT;
-pkgdev = DIST_ROOT=`pwd`/$(dirdev); export DIST_ROOT;
-pkgdi  = DIST_ROOT=`pwd`/$(dirdi); export DIST_ROOT;
+dirheal= debian/$(healpkg)
+pkgme  = DIST_ROOT=`pwd`/$(dirme);   export DIST_ROOT;
+pkgdev = DIST_ROOT=`pwd`/$(dirdev);  export DIST_ROOT;
+pkgdi  = DIST_ROOT=`pwd`/$(dirdi);   export DIST_ROOT;
+pkgheal= DIST_ROOT=`pwd`/$(dirheal); export DIST_ROOT;
 stdenv = @GZIP=-q; export GZIP;
 
 configure_options = \
@@ -103,6 +106,7 @@ binary-arch: checkroot built
 	$(pkgme)  $(MAKE) -C . install-pkg
 	$(pkgdev) $(MAKE) -C . install-dev
 	$(pkgdi)  $(MAKE) -C debian install-d-i
+	$(pkgheal) $(MAKE) -C . install-selfheal
 	$(pkgme)  $(MAKE) dist
 	install -D -m 0755 debian/local/initramfs.hook debian/xfsprogs/usr/share/initramfs-tools/hooks/xfs
 	rmdir debian/xfslibs-dev/usr/share/doc/xfsprogs
@@ -114,7 +118,8 @@ binary-arch: checkroot built
 	dh_compress
 	dh_fixperms
 	dh_makeshlibs
-	dh_installsystemd -p xfsprogs --no-enable --no-start --no-restart-after-upgrade --no-stop-on-upgrade
+	dh_installsystemd -p xfsprogs --no-restart-after-upgrade --no-stop-on-upgrade system-xfs_scrub.slice
+	dh_installsystemd -p xfsprogs-self-healing --no-restart-after-upgrade --no-stop-on-upgrade xfs_scrub_all.timer
 	dh_installdeb
 	dh_shlibdeps
 	dh_gencontrol
diff --git a/doc/Makefile b/doc/Makefile
index ad6749b8d0be..a6ec65f5edc0 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -26,3 +26,6 @@ ifeq ($(PKG_DISTRIBUTION), debian)
 endif
 
 install-dev:
+
+install-selfheal:
+
diff --git a/estimate/Makefile b/estimate/Makefile
index d5f8a6d81d65..4fce3463d55c 100644
--- a/estimate/Makefile
+++ b/estimate/Makefile
@@ -19,4 +19,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/fsck/Makefile b/fsck/Makefile
index ccba7f0b6892..33fca9e18fb0 100644
--- a/fsck/Makefile
+++ b/fsck/Makefile
@@ -17,3 +17,6 @@ install-pkg: default
 	$(INSTALL) -m 755 -d $(PKG_SBIN_DIR)
 	$(INSTALL) -m 755 xfs_fsck.sh $(PKG_SBIN_DIR)/fsck.xfs
 install-dev:
+
+install-selfheal:
+
diff --git a/fsr/Makefile b/fsr/Makefile
index 3ad9f6d824c6..da32bc531970 100644
--- a/fsr/Makefile
+++ b/fsr/Makefile
@@ -22,4 +22,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/growfs/Makefile b/growfs/Makefile
index e0ab870bd6ba..61d184328cf6 100644
--- a/growfs/Makefile
+++ b/growfs/Makefile
@@ -30,4 +30,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/include/Makefile b/include/Makefile
index 23727fccfdcd..c18ab35a9861 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -64,3 +64,6 @@ install-pkg: default
 
 install-dev: install
 	$(INSTALL) -m 644 $(HFILES) $(PKG_INC_DIR)
+
+install-selfheal:
+
diff --git a/io/Makefile b/io/Makefile
index d035420b555c..70c95a5c1425 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -95,4 +95,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 xfs_mkfile.sh $(PKG_SBIN_DIR)/xfs_mkfile
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/libfrog/Makefile b/libfrog/Makefile
index 5ebe36fb58c8..262a4a0f8cda 100644
--- a/libfrog/Makefile
+++ b/libfrog/Makefile
@@ -81,4 +81,6 @@ include $(BUILDRULES)
 
 install install-pkg install-dev: default
 
+install-selfheal:
+
 -include .ltdep
diff --git a/libhandle/Makefile b/libhandle/Makefile
index 7cfd0fa4f27e..28c104a77f95 100644
--- a/libhandle/Makefile
+++ b/libhandle/Makefile
@@ -27,4 +27,6 @@ install-pkg: default
 install-dev: default
 	$(INSTALL_LTLIB_DEV)
 
+install-selfheal:
+
 -include .ltdep
diff --git a/libxcmd/Makefile b/libxcmd/Makefile
index afd5349c8af3..118ecd3cfc88 100644
--- a/libxcmd/Makefile
+++ b/libxcmd/Makefile
@@ -25,4 +25,6 @@ include $(BUILDRULES)
 
 install install-pkg install-dev: default
 
+install-selfheal:
+
 -include .ltdep
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 2c6b45953661..65d4c7619758 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -162,3 +162,6 @@ install-dev: install
 ifndef NODEP
 -include .ltdep
 endif
+
+install-selfheal:
+
diff --git a/libxlog/Makefile b/libxlog/Makefile
index 3710729fe703..37281eb058f2 100644
--- a/libxlog/Makefile
+++ b/libxlog/Makefile
@@ -23,4 +23,6 @@ include $(BUILDRULES)
 
 install install-pkg install-dev: default
 
+install-selfheal:
+
 -include .ltdep
diff --git a/logprint/Makefile b/logprint/Makefile
index 5ec02539a7bb..f1fccbdc8ca7 100644
--- a/logprint/Makefile
+++ b/logprint/Makefile
@@ -28,4 +28,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/m4/Makefile b/m4/Makefile
index eda4c06f6864..b894dd3b0222 100644
--- a/m4/Makefile
+++ b/m4/Makefile
@@ -35,5 +35,7 @@ include $(BUILDRULES)
 
 install install-pkg install-dev install-lib: default
 
+install-selfheal:
+
 realclean: distclean
 	rm -f $(CONFIGURE)
diff --git a/man/Makefile b/man/Makefile
index f62286e8339d..258e8732a923 100644
--- a/man/Makefile
+++ b/man/Makefile
@@ -21,4 +21,6 @@ install-dev : $(addsuffix -install-dev,$(SUBDIRS))
 %-install-dev:
 	$(Q)$(MAKE) $(MAKEOPTS) -C $* install-dev
 
+install-selfheal:
+
 include $(BUILDRULES)
diff --git a/mdrestore/Makefile b/mdrestore/Makefile
index 0d02fb383404..c75d5875929b 100644
--- a/mdrestore/Makefile
+++ b/mdrestore/Makefile
@@ -23,4 +23,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/mkfs/Makefile b/mkfs/Makefile
index cf945aa10c25..515c2db0639d 100644
--- a/mkfs/Makefile
+++ b/mkfs/Makefile
@@ -37,4 +37,6 @@ install-pkg: default
 
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/po/Makefile b/po/Makefile
index 3cc0b4177c64..cb6ef954b695 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -25,3 +25,6 @@ install-pkg: default
 	$(INSTALL_LINGUAS)
 
 install-dev install-lib:
+
+install-selfheal:
+
diff --git a/quota/Makefile b/quota/Makefile
index 01584635b3dd..e1193bd203ad 100644
--- a/quota/Makefile
+++ b/quota/Makefile
@@ -30,4 +30,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/repair/Makefile b/repair/Makefile
index 096ae8c6a5b1..e7979a817d4f 100644
--- a/repair/Makefile
+++ b/repair/Makefile
@@ -113,4 +113,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/rtcp/Makefile b/rtcp/Makefile
index 4adb58c4b783..ac638bcd1029 100644
--- a/rtcp/Makefile
+++ b/rtcp/Makefile
@@ -23,4 +23,6 @@ install-pkg: default
 	$(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_SBIN_DIR)
 install-dev:
 
+install-selfheal:
+
 -include .dep
diff --git a/scrub/Makefile b/scrub/Makefile
index b0022cb7f005..2c349c682d3a 100644
--- a/scrub/Makefile
+++ b/scrub/Makefile
@@ -20,6 +20,7 @@ XFS_SCRUB_ARGS = -p
 XFS_SCRUB_SERVICE_ARGS = -b -o fsprops_advise
 ifeq ($(HAVE_SYSTEMD),yes)
 INSTALL_SCRUB += install-systemd
+INSTALL_SELFHEAL += install-systemd-selfheal
 SYSTEMD_SERVICES=\
 	$(scrub_svcname) \
 	xfs_scrub_fail@.service \
@@ -27,9 +28,10 @@ SYSTEMD_SERVICES=\
 	xfs_scrub_media_fail@.service \
 	xfs_scrub_all.service \
 	xfs_scrub_all_fail.service \
-	xfs_scrub_all.timer \
 	system-xfs_scrub.slice
-OPTIONAL_TARGETS += $(SYSTEMD_SERVICES)
+SYSTEMD_SERVICES_SELFHEAL=\
+	xfs_scrub_all.timer
+OPTIONAL_TARGETS += $(SYSTEMD_SERVICES) $(SYSTEMD_SERVICES_SELFHEAL)
 endif
 ifeq ($(HAVE_CROND),yes)
 INSTALL_SCRUB += install-crond
@@ -163,6 +165,10 @@ install-systemd: default $(SYSTEMD_SERVICES)
 	$(INSTALL) -m 755 -d $(PKG_LIBEXEC_DIR)
 	$(INSTALL) -m 755 $(XFS_SCRUB_FAIL_PROG) $(PKG_LIBEXEC_DIR)
 
+install-systemd-selfheal: default $(SYSTEMD_SERVICES_SELFHEAL)
+	$(INSTALL) -m 755 -d $(SYSTEMD_SYSTEM_UNIT_DIR)
+	$(INSTALL) -m 644 $(SYSTEMD_SERVICES_SELFHEAL) $(SYSTEMD_SYSTEM_UNIT_DIR)
+
 install-crond: default $(CRONTABS)
 	$(INSTALL) -m 755 -d $(CROND_DIR)
 	$(INSTALL) -m 644 $(CRONTABS) $(CROND_DIR)
@@ -181,4 +187,6 @@ install-udev: $(UDEV_RULES)
 
 install-dev:
 
+install-selfheal: $(INSTALL_SELFHEAL)
+
 -include .dep
diff --git a/spaceman/Makefile b/spaceman/Makefile
index 49fbc9290c02..ce1650f99b7c 100644
--- a/spaceman/Makefile
+++ b/spaceman/Makefile
@@ -47,4 +47,6 @@ install-pkg: default
 	$(INSTALL) -m 755 xfs_property $(PKG_SBIN_DIR)/xfs_property
 install-dev:
 
+install-selfheal:
+
 -include .dep


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

* [PATCH 1/1] xfs: functional testing for filesystem properties
  2024-07-30  3:19 ` [PATCHSET v30.9] fstests: xfs filesystem properties Darrick J. Wong
@ 2024-07-30  3:23   ` Darrick J. Wong
  2024-07-30  3:25   ` [PATCHSET v30.9] fstests: xfs " Darrick J. Wong
  1 sibling, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:23 UTC (permalink / raw)
  To: zlang, djwong; +Cc: linux-xfs, fstests

From: Darrick J. Wong <djwong@kernel.org>

Make sure that fs property storage and retrieval actually work.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 common/config      |    1 
 common/xfs         |    4 +-
 tests/xfs/1886     |  135 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/1886.out |   53 ++++++++++++++++++++
 tests/xfs/1887     |  124 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/1887.out |   46 ++++++++++++++++++
 tests/xfs/1888     |   66 +++++++++++++++++++++++++
 tests/xfs/1888.out |    9 +++
 tests/xfs/1889     |   67 ++++++++++++++++++++++++++
 tests/xfs/1889.out |    9 +++
 10 files changed, 512 insertions(+), 2 deletions(-)
 create mode 100755 tests/xfs/1886
 create mode 100644 tests/xfs/1886.out
 create mode 100755 tests/xfs/1887
 create mode 100644 tests/xfs/1887.out
 create mode 100755 tests/xfs/1888
 create mode 100644 tests/xfs/1888.out
 create mode 100755 tests/xfs/1889
 create mode 100644 tests/xfs/1889.out


diff --git a/common/config b/common/config
index 22740c0af8..07bd2cf315 100644
--- a/common/config
+++ b/common/config
@@ -234,6 +234,7 @@ export GZIP_PROG="$(type -P gzip)"
 export BTRFS_IMAGE_PROG="$(type -P btrfs-image)"
 export BTRFS_MAP_LOGICAL_PROG=$(type -P btrfs-map-logical)
 export PARTED_PROG="$(type -P parted)"
+export XFS_PROPERTY_PROG="$(type -P xfs_property)"
 
 # use 'udevadm settle' or 'udevsettle' to wait for lv to be settled.
 # newer systems have udevadm command but older systems like RHEL5 don't.
diff --git a/common/xfs b/common/xfs
index bd40a02ed2..a642646345 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1318,8 +1318,8 @@ _require_xfs_spaceman_command()
 	testfile=$TEST_DIR/$$.xfs_spaceman
 	touch $testfile
 	case $command in
-	"health")
-		testio=`$XFS_SPACEMAN_PROG -c "health $param" $TEST_DIR 2>&1`
+	"health"|"listfsprops")
+		testio=`$XFS_SPACEMAN_PROG -c "$command $param" $TEST_DIR 2>&1`
 		param_checked=1
 		;;
 	*)
diff --git a/tests/xfs/1886 b/tests/xfs/1886
new file mode 100755
index 0000000000..eca76f51d6
--- /dev/null
+++ b/tests/xfs/1886
@@ -0,0 +1,135 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2024 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1886
+#
+# Functional testing for low level filesystem property manipulation by
+# xfs_{spaceman,db}.
+#
+. ./common/preamble
+_begin_fstest auto
+
+. ./common/filter
+. ./common/attr
+
+_require_test
+_require_user fsgqa
+_require_attrs
+_require_xfs_spaceman_command listfsprops
+_require_xfs_db_command attr_list
+
+_cleanup()
+
+{
+	cd /
+	rm -r -f $tmp.*
+	rm -f $TEST_DIR/$seq.somefile
+	rm -r -f $TEST_DIR/$seq.somedir
+}
+
+filter_inum()
+{
+	sed -e 's/inode [0-9]*/inode XXX/g'
+}
+
+propname="fakeproperty"	# must not be an actual property
+propval="1721943740"
+longpropname="$(perl -e 'print "x" x 300;')"
+longpropval="$(perl -e 'print "x" x 80000;')"
+
+echo "*** SPACEMAN TEST ***"
+
+echo empty get property
+$XFS_SPACEMAN_PROG -c "getfsprops $propname" $TEST_DIR
+
+echo pointless remove property
+$XFS_SPACEMAN_PROG -c "removefsprops $propname" $TEST_DIR
+
+echo list property
+$XFS_SPACEMAN_PROG -c "listfsprops" $TEST_DIR | grep $propname
+
+echo set property
+$XFS_SPACEMAN_PROG -c "setfsprops $propname=$propval" $TEST_DIR
+
+echo list property
+$XFS_SPACEMAN_PROG -c "listfsprops" $TEST_DIR | grep $propname
+
+echo dump xattrs
+$ATTR_PROG -R -l $TEST_DIR | | grep $propname | _filter_test_dir
+
+echo get property
+$XFS_SPACEMAN_PROG -c "getfsprops $propname" $TEST_DIR
+
+echo list property
+$XFS_SPACEMAN_PROG -c "listfsprops" $TEST_DIR | grep $propname
+
+echo child file rejected
+touch $TEST_DIR/$seq.somefile
+$XFS_SPACEMAN_PROG -c "listfsprops $propname" $TEST_DIR/$seq.somefile 2>&1 | \
+	_filter_test_dir
+
+echo child dir accepted
+mkdir -p $TEST_DIR/$seq.somedir
+$XFS_SPACEMAN_PROG -c "listfsprops $propname" $TEST_DIR/$seq.somedir | grep $propname
+
+echo remove property
+$XFS_SPACEMAN_PROG -c "removefsprops $propname" $TEST_DIR
+
+echo pointless remove property
+$XFS_SPACEMAN_PROG -c "removefsprops $propname" $TEST_DIR
+
+echo set too long name
+$XFS_SPACEMAN_PROG -c "setfsprops $longpropname=$propval" $TEST_DIR
+
+echo set too long value
+$XFS_SPACEMAN_PROG -c "setfsprops $propname=$longpropval" $TEST_DIR
+
+echo not enough permissions
+su - "$qa_user" -c "$XFS_SPACEMAN_PROG -c \"setfsprops $propname=$propval\" $TEST_DIR" 2>&1 | _filter_test_dir
+
+echo "*** DB TEST ***"
+
+propval=$((propval + 1))
+_test_unmount
+
+echo empty get property
+_test_xfs_db -x -c 'path /' -c "attr_get -Z $propname" 2>&1 | filter_inum
+
+echo pointless remove property
+_test_xfs_db -x -c 'path /' -c "attr_remove -Z $propname" 2>&1 | filter_inum
+
+echo list property
+_test_xfs_db -x -c 'path /' -c "attr_list -Z" | grep $propname
+
+echo set property
+_test_xfs_db -x -c 'path /' -c "attr_set -Z $propname $propval"
+
+echo list property
+_test_xfs_db -x -c 'path /' -c "attr_list -Z" | grep $propname
+
+echo dump xattrs
+_test_mount
+$ATTR_PROG -R -l $TEST_DIR | grep $propname | _filter_test_dir
+_test_unmount
+
+echo get property
+_test_xfs_db -x -c 'path /' -c "attr_get -Z $propname"
+
+echo list property
+_test_xfs_db -x -c 'path /' -c "attr_list -Z" | grep $propname
+
+echo remove property
+_test_xfs_db -x -c 'path /' -c "attr_remove -Z $propname"
+
+echo pointless remove property
+_test_xfs_db -x -c 'path /' -c "attr_remove -Z $propname" 2>&1 | filter_inum
+
+echo set too long name
+_test_xfs_db -x -c 'path /' -c "attr_set -Z $longpropname $propval"
+
+echo set too long value
+_test_xfs_db -x -c 'path /' -c "attr_set -Z $propname $longpropval"
+
+status=0
+exit
diff --git a/tests/xfs/1886.out b/tests/xfs/1886.out
new file mode 100644
index 0000000000..2f05c8b7c5
--- /dev/null
+++ b/tests/xfs/1886.out
@@ -0,0 +1,53 @@
+QA output created by 1886
+*** SPACEMAN TEST ***
+empty get property
+fakeproperty: No data available
+pointless remove property
+fakeproperty: No data available
+list property
+set property
+fakeproperty=1721943740
+list property
+fakeproperty
+dump xattrs
+Attribute "xfs:fakeproperty" has a 10 byte value for TEST_DIR
+get property
+fakeproperty=1721943740
+list property
+fakeproperty
+child file rejected
+TEST_DIR/1886.somefile: Not a directory
+child dir accepted
+fakeproperty
+remove property
+pointless remove property
+fakeproperty: No data available
+set too long name
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: Invalid argument
+set too long value
+fakeproperty: Invalid argument
+not enough permissions
+TEST_DIR: Operation not permitted
+*** DB TEST ***
+empty get property
+failed to get attr xfs:fakeproperty on inode XXX: No data available
+pointless remove property
+failed to remove attr xfs:fakeproperty from inode XXX: No data available
+list property
+set property
+fakeproperty=1721943741
+list property
+fakeproperty
+dump xattrs
+Attribute "xfs:fakeproperty" has a 10 byte value for TEST_DIR
+get property
+fakeproperty=1721943741
+list property
+fakeproperty
+remove property
+pointless remove property
+failed to remove attr xfs:fakeproperty from inode XXX: No data available
+set too long name
+name too long
+set too long value
+xfs:fakeproperty: value too long
diff --git a/tests/xfs/1887 b/tests/xfs/1887
new file mode 100755
index 0000000000..fe75abe2c5
--- /dev/null
+++ b/tests/xfs/1887
@@ -0,0 +1,124 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2024 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1887
+#
+# Functional testing for xfs_property the wrapper script.
+#
+. ./common/preamble
+_begin_fstest auto
+
+. ./common/filter
+. ./common/attr
+
+_require_test
+_require_attrs
+
+# XXX yeah
+test -z "$XFS_PROPERTY_PROG" && \
+	XFS_PROPERTY_PROG="$(type -P xfs_property.sh)"
+
+_require_command "$XFS_PROPERTY_PROG" xfs_property
+_require_xfs_spaceman_command listfsprops	# actually detect support
+
+_cleanup()
+
+{
+	cd /
+	rm -r -f $tmp.*
+}
+
+filter_inum()
+{
+	sed -e 's/inode [0-9]*/inode XXX/g'
+}
+
+propname="fakeproperty"	# must not be an actual property
+propval="1721943742"
+longpropname="$(perl -e 'print "x" x 300;')"
+longpropval="$(perl -e 'print "x" x 80000;')"
+
+echo "*** OFFLINE XFS_PROPERTY TEST ***"
+
+_test_unmount
+
+echo empty get property
+$XFS_PROPERTY_PROG $TEST_DEV get "$propname" 2>&1 | filter_inum
+
+echo pointless remove property
+$XFS_PROPERTY_PROG $TEST_DEV remove "$propname" 2>&1 | filter_inum
+
+echo list property
+$XFS_PROPERTY_PROG $TEST_DEV list | grep $propname
+
+echo set property
+$XFS_PROPERTY_PROG $TEST_DEV set "$propname=$propval"
+
+echo list property
+$XFS_PROPERTY_PROG $TEST_DEV list | grep $propname
+
+echo dump xattrs
+$ATTR_PROG -R -l $TEST_DEV | grep $propname | _filter_test_dir
+
+echo get property
+$XFS_PROPERTY_PROG $TEST_DEV get "$propname"
+
+echo list property
+$XFS_PROPERTY_PROG $TEST_DEV list | grep $propname
+
+echo remove property
+$XFS_PROPERTY_PROG $TEST_DEV remove "$propname"
+
+echo pointless remove property
+$XFS_PROPERTY_PROG $TEST_DEV remove "$propname" 2>&1 | filter_inum
+
+echo set too long name
+$XFS_PROPERTY_PROG $TEST_DEV set "$longpropname=$propval"
+
+echo set too long value
+$XFS_PROPERTY_PROG $TEST_DEV set "$propname=$longpropval"
+
+echo "*** ONLINE XFS_PROPERTY TEST ***"
+
+propval=$((propval+1))
+_test_mount
+
+echo empty get property
+$XFS_PROPERTY_PROG $TEST_DIR get "$propname"
+
+echo pointless remove property
+$XFS_PROPERTY_PROG $TEST_DIR remove "$propname"
+
+echo list property
+$XFS_PROPERTY_PROG $TEST_DIR list | grep $propname
+
+echo set property
+$XFS_PROPERTY_PROG $TEST_DIR set "$propname=$propval"
+
+echo list property
+$XFS_PROPERTY_PROG $TEST_DIR list | grep $propname
+
+echo dump xattrs
+$ATTR_PROG -R -l $TEST_DIR | grep $propname | _filter_test_dir
+
+echo get property
+$XFS_PROPERTY_PROG $TEST_DIR get "$propname"
+
+echo list property
+$XFS_PROPERTY_PROG $TEST_DIR list | grep $propname
+
+echo remove property
+$XFS_PROPERTY_PROG $TEST_DIR remove "$propname"
+
+echo pointless remove property
+$XFS_PROPERTY_PROG $TEST_DIR remove "$propname"
+
+echo set too long name
+$XFS_PROPERTY_PROG $TEST_DIR set "$longpropname=$propval"
+
+echo set too long value
+$XFS_PROPERTY_PROG $TEST_DIR set "$propname=$longpropval"
+
+status=0
+exit
diff --git a/tests/xfs/1887.out b/tests/xfs/1887.out
new file mode 100644
index 0000000000..2c27206acf
--- /dev/null
+++ b/tests/xfs/1887.out
@@ -0,0 +1,46 @@
+QA output created by 1887
+*** OFFLINE XFS_PROPERTY TEST ***
+empty get property
+failed to get attr xfs:fakeproperty on inode XXX: No data available
+pointless remove property
+failed to remove attr xfs:fakeproperty from inode XXX: No data available
+list property
+set property
+fakeproperty=1721943742
+list property
+fakeproperty
+dump xattrs
+get property
+fakeproperty=1721943742
+list property
+fakeproperty
+remove property
+pointless remove property
+failed to remove attr xfs:fakeproperty from inode XXX: No data available
+set too long name
+name too long
+set too long value
+xfs:fakeproperty: value too long
+*** ONLINE XFS_PROPERTY TEST ***
+empty get property
+fakeproperty: No data available
+pointless remove property
+fakeproperty: No data available
+list property
+set property
+fakeproperty=1721943743
+list property
+fakeproperty
+dump xattrs
+Attribute "xfs:fakeproperty" has a 10 byte value for TEST_DIR
+get property
+fakeproperty=1721943743
+list property
+fakeproperty
+remove property
+pointless remove property
+fakeproperty: No data available
+set too long name
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx: Invalid argument
+set too long value
+fakeproperty: Invalid argument
diff --git a/tests/xfs/1888 b/tests/xfs/1888
new file mode 100755
index 0000000000..8d54343cc2
--- /dev/null
+++ b/tests/xfs/1888
@@ -0,0 +1,66 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2024 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1888
+#
+# Functional testing for mkfs applying self_healing fs property.
+#
+. ./common/preamble
+_begin_fstest auto
+
+. ./common/filter
+. ./common/attr
+
+_require_test
+_require_xfs_spaceman_command listfsprops	# needed for fs props
+_require_xfs_db_command attr_get
+
+_cleanup()
+
+{
+	cd /
+	rm -r -f $tmp.*
+	rm -f $dummyfile
+	rmdir $dummymnt
+}
+
+dummyfile=$TEST_DIR/$seq.somefile
+dummymnt=$TEST_DIR/$seq.mount
+
+truncate -s 10g $dummyfile
+mkdir -p $dummymnt
+
+filter_inum()
+{
+	sed -e 's/inode [0-9]*/inode XXX/g'
+}
+
+testme() {
+	local mkfs_args=('-f')
+	local value="$1"
+	test -n "$value" && value="=$value"
+
+	if [ $# -gt 0 ]; then
+		mkfs_args+=('-m' "self_healing$value")
+	fi
+
+	echo "testing ${mkfs_args[*]}" >> $seqres.full
+
+	$MKFS_XFS_PROG $MKFS_OPTIONS "${mkfs_args[@]}" $dummyfile >> $seqres.full || \
+		_notrun "mkfs.xfs ${mkfs_args[*]} failed?"
+
+	$XFS_DB_PROG -x -c 'path /' -c "attr_get -Z self_healing" $dummyfile 2>&1 | filter_inum
+}
+
+testme ''
+testme
+testme none
+testme check
+testme optimize
+testme repair
+testme 0
+testme 1
+
+status=0
+exit
diff --git a/tests/xfs/1888.out b/tests/xfs/1888.out
new file mode 100644
index 0000000000..d386d01b8f
--- /dev/null
+++ b/tests/xfs/1888.out
@@ -0,0 +1,9 @@
+QA output created by 1888
+self_healing=repair
+failed to get attr xfs:self_healing on inode XXX: No data available
+self_healing=none
+self_healing=check
+self_healing=optimize
+self_healing=repair
+self_healing=none
+self_healing=repair
diff --git a/tests/xfs/1889 b/tests/xfs/1889
new file mode 100755
index 0000000000..623f004631
--- /dev/null
+++ b/tests/xfs/1889
@@ -0,0 +1,67 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2024 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1889
+#
+# Functional testing for mkfs applying self_healing fs property and xfs_scrub
+# changing its behavior accordingly.  Or at least claiming to.
+#
+. ./common/preamble
+_begin_fstest auto
+
+. ./common/filter
+. ./common/fuzzy
+
+_require_test
+_require_xfs_spaceman_command listfsprops	# needed for fs props
+_require_xfs_db_command attr_get
+_require_scrub
+
+_cleanup()
+
+{
+	cd /
+	rm -r -f $tmp.*
+	rm -f $dummyfile
+	_umount $dummymnt &>/dev/null
+	rmdir $dummymnt
+}
+
+dummyfile=$TEST_DIR/$seq.somefile
+dummymnt=$TEST_DIR/$seq.mount
+
+truncate -s 10g $dummyfile
+mkdir -p $dummymnt
+
+testme() {
+	local mkfs_args=('-f')
+	local value="$1"
+	test -n "$value" && value="=$value"
+
+	if [ $# -gt 0 ]; then
+		mkfs_args+=('-m' "self_healing$value")
+	fi
+
+	echo "testing ${mkfs_args[*]}" >> $seqres.full
+
+	$MKFS_XFS_PROG $MKFS_OPTIONS "${mkfs_args[@]}" $dummyfile >> $seqres.full || \
+		_notrun "mkfs.xfs ${mkfs_args[*]} failed?"
+
+	_mount -o loop $dummyfile $dummymnt
+	XFS_SCRUB_PHASE=7 $XFS_SCRUB_PROG -d -o fsprops_advise $dummymnt 2>&1 | \
+		grep self_healing | _filter_test_dir | sed -e 's/\(directive.\).*$/\1/g'
+	_umount $dummymnt
+}
+
+testme ''
+testme
+testme none
+testme check
+testme optimize
+testme repair
+testme 0
+testme 1
+
+status=0
+exit
diff --git a/tests/xfs/1889.out b/tests/xfs/1889.out
new file mode 100644
index 0000000000..707c37edd0
--- /dev/null
+++ b/tests/xfs/1889.out
@@ -0,0 +1,9 @@
+QA output created by 1889
+Info: TEST_DIR/1889.mount: Checking and repairing per self_healing directive.
+Info: TEST_DIR/1889.mount: Checking per self_healing directive.
+Info: TEST_DIR/1889.mount: Disabling scrub per self_healing directive.
+Info: TEST_DIR/1889.mount: Checking per self_healing directive.
+Info: TEST_DIR/1889.mount: Optimizing per self_healing directive.
+Info: TEST_DIR/1889.mount: Checking and repairing per self_healing directive.
+Info: TEST_DIR/1889.mount: Disabling scrub per self_healing directive.
+Info: TEST_DIR/1889.mount: Checking and repairing per self_healing directive.


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

* Re: [PATCHSET v30.9] fstests: xfs filesystem properties
  2024-07-30  3:19 ` [PATCHSET v30.9] fstests: xfs filesystem properties Darrick J. Wong
  2024-07-30  3:23   ` [PATCH 1/1] xfs: functional testing for " Darrick J. Wong
@ 2024-07-30  3:25   ` Darrick J. Wong
  1 sibling, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30  3:25 UTC (permalink / raw)
  To: zlang; +Cc: linux-xfs, fstests

On Mon, Jul 29, 2024 at 08:19:43PM -0700, Darrick J. Wong wrote:
> Hi all,
> 
> It would be very useful if system administrators could set properties for a
> given xfs filesystem to control its behavior.  This we can do easily and
> extensibly by setting ATTR_ROOT (aka "trusted") extended attributes on the root
> directory.  To prevent this from becoming a weird free for all, let's add some
> library and tooling support so that sysadmins simply run the xfs_property
> program to administer these properties.

Heh, I forgot to cc the patchbomb coverletter -- this is an RFC, not for
merging at this time.

--D

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

* Re: [PATCH 3/7] xfs_db: improve getting and setting extended attributes
  2024-07-30  3:20   ` [PATCH 3/7] xfs_db: improve getting and setting extended attributes Darrick J. Wong
@ 2024-07-30 21:37     ` Christoph Hellwig
  0 siblings, 0 replies; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-30 21:37 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: cem, linux-xfs

> +static int		attr_get_f(int argc, char **argv);
>  static int		attr_set_f(int argc, char **argv);
>  static int		attr_remove_f(int argc, char **argv);
> +static void		attrget_help(void);
>  static void		attrset_help(void);

I always hate these forward declarations, but I guess it matches the
existing code..

Otherwise looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 4/7] libxfs: hoist listxattr from xfs_repair
  2024-07-30  3:20   ` [PATCH 4/7] libxfs: hoist listxattr from xfs_repair Darrick J. Wong
@ 2024-07-30 21:38     ` Christoph Hellwig
  2024-07-31 17:55       ` Darrick J. Wong
  0 siblings, 1 reply; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-30 21:38 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: cem, linux-xfs

On Mon, Jul 29, 2024 at 08:20:45PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Hoist the listxattr code from xfs_repair so that we can use it in
> xfs_db.

I guess there isn't much of a point in sharing with the kernel listattr
code?

But maybe that is for later, for now this trivial move looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 5/7] libxfs: pass a transaction context through listxattr
  2024-07-30  3:21   ` [PATCH 5/7] libxfs: pass a transaction context through listxattr Darrick J. Wong
@ 2024-07-30 21:38     ` Christoph Hellwig
  0 siblings, 0 replies; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-30 21:38 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: cem, linux-xfs

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>


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

* Re: [PATCH 6/7] xfs_db: add a command to list xattrs
  2024-07-30  3:21   ` [PATCH 6/7] xfs_db: add a command to list xattrs Darrick J. Wong
@ 2024-07-30 21:39     ` Christoph Hellwig
  0 siblings, 0 replies; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-30 21:39 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: cem, linux-xfs

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 1/7] libfrog: support editing filesystem property sets
  2024-07-30  3:19   ` [PATCH 1/7] libfrog: support editing filesystem property sets Darrick J. Wong
@ 2024-07-30 21:40     ` Christoph Hellwig
  0 siblings, 0 replies; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-30 21:40 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: cem, linux-xfs

Looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>


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

* Re: [PATCH 2/7] xfs_spaceman: edit filesystem properties
  2024-07-30  3:20   ` [PATCH 2/7] xfs_spaceman: edit filesystem properties Darrick J. Wong
@ 2024-07-30 21:41     ` Christoph Hellwig
  2024-07-30 22:37       ` Darrick J. Wong
  0 siblings, 1 reply; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-30 21:41 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: cem, linux-xfs

Is this really a xfs_spaceman thingy?  The code itself looks fine,
but the association with space management is kinda weird.


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

* Re: [PATCH 7/7] xfs_property: add a new tool to administer fs properties
  2024-07-30  3:21   ` [PATCH 7/7] xfs_property: add a new tool to administer fs properties Darrick J. Wong
@ 2024-07-30 21:43     ` Christoph Hellwig
  2024-07-30 22:28       ` Darrick J. Wong
  2024-08-02  0:25     ` Dave Chinner
  1 sibling, 1 reply; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-30 21:43 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: cem, linux-xfs

On Mon, Jul 29, 2024 at 08:21:32PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Create a tool to list, get, set, and remove filesystem properties.

Ok, so this wraps spaceman.  Can we make the property manipulation only
available through this interface to cause less confusion?


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

* Re: [PATCH 1/3] libfrog: define a self_healing filesystem property
  2024-07-30  3:21   ` [PATCH 1/3] libfrog: define a self_healing filesystem property Darrick J. Wong
@ 2024-07-30 21:56     ` Christoph Hellwig
  2024-07-30 23:51       ` Darrick J. Wong
  0 siblings, 1 reply; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-30 21:56 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: cem, linux-xfs

self-healing sounds a little imposterous :)

The code itself looks fine though.


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

* Re: [PATCH 7/7] xfs_property: add a new tool to administer fs properties
  2024-07-30 21:43     ` Christoph Hellwig
@ 2024-07-30 22:28       ` Darrick J. Wong
  2024-07-31 15:42         ` Christoph Hellwig
  0 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30 22:28 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: cem, linux-xfs

On Tue, Jul 30, 2024 at 02:43:30PM -0700, Christoph Hellwig wrote:
> On Mon, Jul 29, 2024 at 08:21:32PM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> > 
> > Create a tool to list, get, set, and remove filesystem properties.
> 
> Ok, so this wraps spaceman.  Can we make the property manipulation only
> available through this interface to cause less confusion?

I think you're asking if I could make xfs_spaceman expose the
{list,get,set}fsprops commands and db expose the -Z flag to
attr_{get,set,list} when someone starts them up with -p xfs_property ?

If so, then yes, I can do that.

--D

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

* Re: [PATCH 2/7] xfs_spaceman: edit filesystem properties
  2024-07-30 21:41     ` Christoph Hellwig
@ 2024-07-30 22:37       ` Darrick J. Wong
  2024-07-31 15:41         ` Christoph Hellwig
  0 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30 22:37 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: cem, linux-xfs

On Tue, Jul 30, 2024 at 02:41:41PM -0700, Christoph Hellwig wrote:
> Is this really a xfs_spaceman thingy?  The code itself looks fine,
> but the association with space management is kinda weird.

I dunno.  It could just as easily go into xfs_io I suppose; the tiny
advantage of putting it in spaceman is that spaceman grabs the
fsgeometry structure on file open so we don't have to do that again.

--D

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

* Re: [PATCH 1/3] libfrog: define a self_healing filesystem property
  2024-07-30 21:56     ` Christoph Hellwig
@ 2024-07-30 23:51       ` Darrick J. Wong
  2024-07-31 15:43         ` Christoph Hellwig
  0 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-30 23:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: cem, linux-xfs

On Tue, Jul 30, 2024 at 02:56:50PM -0700, Christoph Hellwig wrote:
> self-healing sounds a little imposterous :)

Do you have a better suggestion?

"auto_fsck"?

"auto_unf***"? ;)

"background_fsck"?

"background_scrub"?

"patrol_scrub"? <ugh>

> The code itself looks fine though.

--D

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

* Re: [PATCH 2/7] xfs_spaceman: edit filesystem properties
  2024-07-30 22:37       ` Darrick J. Wong
@ 2024-07-31 15:41         ` Christoph Hellwig
  2024-08-02  0:16           ` Dave Chinner
  0 siblings, 1 reply; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-31 15:41 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, cem, linux-xfs

On Tue, Jul 30, 2024 at 03:37:25PM -0700, Darrick J. Wong wrote:
> On Tue, Jul 30, 2024 at 02:41:41PM -0700, Christoph Hellwig wrote:
> > Is this really a xfs_spaceman thingy?  The code itself looks fine,
> > but the association with space management is kinda weird.
> 
> I dunno.  It could just as easily go into xfs_io I suppose; the tiny
> advantage of putting it in spaceman is that spaceman grabs the
> fsgeometry structure on file open so we don't have to do that again.

For the online changes xfs_io seems ok, and for the offline ones xfs_db
seems like a perfevt fit anyway.


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

* Re: [PATCH 7/7] xfs_property: add a new tool to administer fs properties
  2024-07-30 22:28       ` Darrick J. Wong
@ 2024-07-31 15:42         ` Christoph Hellwig
  2024-07-31 17:56           ` Darrick J. Wong
  0 siblings, 1 reply; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-31 15:42 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, cem, linux-xfs

On Tue, Jul 30, 2024 at 03:28:15PM -0700, Darrick J. Wong wrote:
> I think you're asking if I could make xfs_spaceman expose the
> {list,get,set}fsprops commands and db expose the -Z flag to
> attr_{get,set,list} when someone starts them up with -p xfs_property ?

I was mostly concerned about spaceman.  I don't think it actually is so
bad, just a bit confusing.  But if we do xfs_io and xfs_db that's not
really an issue anyway.


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

* Re: [PATCH 1/3] libfrog: define a self_healing filesystem property
  2024-07-30 23:51       ` Darrick J. Wong
@ 2024-07-31 15:43         ` Christoph Hellwig
  2024-07-31 17:45           ` Darrick J. Wong
  0 siblings, 1 reply; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-31 15:43 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, cem, linux-xfs

On Tue, Jul 30, 2024 at 04:51:03PM -0700, Darrick J. Wong wrote:
> On Tue, Jul 30, 2024 at 02:56:50PM -0700, Christoph Hellwig wrote:
> > self-healing sounds a little imposterous :)
> 
> Do you have a better suggestion?

Heh.  Maybe actually make it to separate ones?
auto_scrub and auto_repair?


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

* Re: [PATCH 1/3] libfrog: define a self_healing filesystem property
  2024-07-31 15:43         ` Christoph Hellwig
@ 2024-07-31 17:45           ` Darrick J. Wong
  2024-07-31 19:43             ` Christoph Hellwig
  0 siblings, 1 reply; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-31 17:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: cem, linux-xfs

On Wed, Jul 31, 2024 at 08:43:19AM -0700, Christoph Hellwig wrote:
> On Tue, Jul 30, 2024 at 04:51:03PM -0700, Darrick J. Wong wrote:
> > On Tue, Jul 30, 2024 at 02:56:50PM -0700, Christoph Hellwig wrote:
> > > self-healing sounds a little imposterous :)
> > 
> > Do you have a better suggestion?
> 
> Heh.  Maybe actually make it to separate ones?
> auto_scrub and auto_repair?

I don't want multiple attributes because that enables sysadmins to give
us mixed messages.  What happens if we encounter this:

auto_scrub=no
auto_repair=yes
auto_optimize=paula

?

Better just to have one attribute and make them pick the one they want.

How about auto_fsck={none,check,optimize,repair} ?

--D

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

* Re: [PATCH 4/7] libxfs: hoist listxattr from xfs_repair
  2024-07-30 21:38     ` Christoph Hellwig
@ 2024-07-31 17:55       ` Darrick J. Wong
  0 siblings, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-31 17:55 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: cem, linux-xfs

On Tue, Jul 30, 2024 at 02:38:08PM -0700, Christoph Hellwig wrote:
> On Mon, Jul 29, 2024 at 08:20:45PM -0700, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> > 
> > Hoist the listxattr code from xfs_repair so that we can use it in
> > xfs_db.
> 
> I guess there isn't much of a point in sharing with the kernel listattr
> code?
> 
> But maybe that is for later, for now this trivial move looks good:

I think we could do it.  The major difference between the two is the
prefix we use for the dabno "have I seen this block before?" bitmap
functions.  But that and the scrub/listxattr.c code would both have to
be lifted to libxfs, and as long as we're doing that we might as well
clean up the userspace bitmap implementation.

(IOWs that's a somewhat lengthy cleanup for userspace either for after
we get the rt modernization stuff merged or if we get really bored
sitting in meetings.)

> Reviewed-by: Christoph Hellwig <hch@lst.de>

Thank you!

--D

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

* Re: [PATCH 7/7] xfs_property: add a new tool to administer fs properties
  2024-07-31 15:42         ` Christoph Hellwig
@ 2024-07-31 17:56           ` Darrick J. Wong
  0 siblings, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-07-31 17:56 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: cem, linux-xfs

On Wed, Jul 31, 2024 at 08:42:41AM -0700, Christoph Hellwig wrote:
> On Tue, Jul 30, 2024 at 03:28:15PM -0700, Darrick J. Wong wrote:
> > I think you're asking if I could make xfs_spaceman expose the
> > {list,get,set}fsprops commands and db expose the -Z flag to
> > attr_{get,set,list} when someone starts them up with -p xfs_property ?
> 
> I was mostly concerned about spaceman.  I don't think it actually is so
> bad, just a bit confusing.  But if we do xfs_io and xfs_db that's not
> really an issue anyway.

Fair 'enough.  I'll see about switching spaceman -> io today.

--D

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

* Re: [PATCH 1/3] libfrog: define a self_healing filesystem property
  2024-07-31 17:45           ` Darrick J. Wong
@ 2024-07-31 19:43             ` Christoph Hellwig
  0 siblings, 0 replies; 42+ messages in thread
From: Christoph Hellwig @ 2024-07-31 19:43 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, cem, linux-xfs

On Wed, Jul 31, 2024 at 10:45:31AM -0700, Darrick J. Wong wrote:
> Better just to have one attribute and make them pick the one they want.
> 
> How about auto_fsck={none,check,optimize,repair} ?

Sounds good.


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

* Re: [PATCH 2/7] xfs_spaceman: edit filesystem properties
  2024-07-31 15:41         ` Christoph Hellwig
@ 2024-08-02  0:16           ` Dave Chinner
  0 siblings, 0 replies; 42+ messages in thread
From: Dave Chinner @ 2024-08-02  0:16 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Darrick J. Wong, cem, linux-xfs

On Wed, Jul 31, 2024 at 08:41:58AM -0700, Christoph Hellwig wrote:
> On Tue, Jul 30, 2024 at 03:37:25PM -0700, Darrick J. Wong wrote:
> > On Tue, Jul 30, 2024 at 02:41:41PM -0700, Christoph Hellwig wrote:
> > > Is this really a xfs_spaceman thingy?  The code itself looks fine,
> > > but the association with space management is kinda weird.
> > 
> > I dunno.  It could just as easily go into xfs_io I suppose; the tiny
> > advantage of putting it in spaceman is that spaceman grabs the
> > fsgeometry structure on file open so we don't have to do that again.
> 
> For the online changes xfs_io seems ok, and for the offline ones xfs_db
> seems like a perfevt fit anyway.

If fsprops can be managed both online and offline,
then xfs_admin is probably the right user facing interface
to document.  i.e. We already have xfs_admin vectoring between
xfs_io when the filesystem is online and xfs_db when the filesystem
is offline to do things like change UUIDs and labels. This would
make setting fsprops somewhat simpler for admins and scripts as they
then only have to learn/code one mechanism instead of two...

-Dave.
-- 
Dave Chinner
david@fromorbit.com

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

* Re: [PATCH 7/7] xfs_property: add a new tool to administer fs properties
  2024-07-30  3:21   ` [PATCH 7/7] xfs_property: add a new tool to administer fs properties Darrick J. Wong
  2024-07-30 21:43     ` Christoph Hellwig
@ 2024-08-02  0:25     ` Dave Chinner
  1 sibling, 0 replies; 42+ messages in thread
From: Dave Chinner @ 2024-08-02  0:25 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: cem, linux-xfs

On Mon, Jul 29, 2024 at 08:21:32PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Create a tool to list, get, set, and remove filesystem properties.
> 
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
>  man/man8/xfs_property.8 |   52 ++++++++++++++++++++++++++++++++
>  spaceman/Makefile       |    3 +-
>  spaceman/xfs_property   |   77 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 131 insertions(+), 1 deletion(-)
>  create mode 100644 man/man8/xfs_property.8
>  create mode 100755 spaceman/xfs_property

Ah, there's the admin wrapper. :)

I should have read the whole patch set before commenting.

> diff --git a/man/man8/xfs_property.8 b/man/man8/xfs_property.8
> new file mode 100644
> index 000000000000..63245331bd86
> --- /dev/null
> +++ b/man/man8/xfs_property.8
> @@ -0,0 +1,52 @@
> +.TH xfs_property 8
> +.SH NAME
> +xfs_property \- examine and edit properties about an XFS filesystem
> +.SH SYNOPSIS
> +.B xfs_property
> +.I target
> +.B get
> +.IR name ...
> +.br
> +.B xfs_property
> +.I target
> +.B list [ \-v ]
> +.br
> +.B xfs_property
> +.I target
> +.B set
> +.IR name=value ...
> +.br
> +.B xfs_property
> +.I target
> +.B remove
> +.IR name ...
> +.br
> +.B xfs_property \-V
> +.SH DESCRIPTION
> +.B xfs_property
> +retrieves, lists, sets, or removes properties of an XFS filesystem.
> +Filesystem properties are root-controlled attributes set on the root directory
> +of the filesystem to enable the system administrator to coordinate with
> +userspace programs.
> +
> +.SH COMMANDS
> +.TP
> +.B get
> +.IR name ...
> +Prints the values of the given filesystem properties.
> +.TP
> +.B list
> +Lists the names of all filesystem properties.
> +If the
> +.B -v
> +flag is specified, prints the values as well.
> +.TP
> +.B set
> +.IR name = value ...
> +Sets the given filesystem properties to the specified values and prints what
> +was set.
> +.TP
> +.B
> +remove
> +.IR name ...
> +Unsets the given filesystem properties.

What does the -V option do? It's documented as existing, but not
explained.

Otherwise looks fine.

-Dave.
-- 
Dave Chinner
david@fromorbit.com

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

* Re: [RFC PATCHSET] xfsprogs: filesystem properties
  2024-07-30  3:10 [RFC PATCHSET] xfsprogs: filesystem properties Darrick J. Wong
                   ` (3 preceding siblings ...)
  2024-07-30  3:19 ` [PATCHSET v30.9] fstests: xfs filesystem properties Darrick J. Wong
@ 2024-08-02  0:29 ` Dave Chinner
  4 siblings, 0 replies; 42+ messages in thread
From: Dave Chinner @ 2024-08-02  0:29 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Christoph Hellwig, xfs

On Mon, Jul 29, 2024 at 08:10:30PM -0700, Darrick J. Wong wrote:
> Hi all,
> 
> After last week's discussion about how to allow sysadmins to opt in or
> out of autonomous self healing XFS[1], I now have an RFC patchset that
> implements the filesystem properties that we talked about.
> 
> As a refresher, the design I settled on is to add ATTR_ROOT (aka
> "trusted") xattrs to the root directory.  ATTR_ROOT xattrs can only be
> accessed by processes with CAP_SYS_ADMIN, so unprivileged userspace
> can't mess with the sysadmin's configured preferences.
> 
> I decided that all fs properties should have "xfs:" in the name to make
> them look distinct, and defined "trusted.xfs:self_healing" as the
> property that controls the amount of autonomous self healing.  There's a
> new wrapper program "xfs_property" that one can use to administer the
> properties.  xfs_scrub{,bed} uses the property; and mkfs.xfs can set it
> for you at format time.

Overall this approach looks fine to me.

Acked-by: Dave Chinner <dchinner@redhat.com>

-Dave.

-- 
Dave Chinner
david@fromorbit.com

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

* [PATCH 4/7] libxfs: hoist listxattr from xfs_repair
  2024-08-06 18:18 [PATCHSET v30.10 1/3] " Darrick J. Wong
@ 2024-08-06 18:20 ` Darrick J. Wong
  0 siblings, 0 replies; 42+ messages in thread
From: Darrick J. Wong @ 2024-08-06 18:20 UTC (permalink / raw)
  To: djwong, cem
  Cc: Christoph Hellwig, Dave Chinner, hch, dchinner, fstests,
	linux-xfs

From: Darrick J. Wong <djwong@kernel.org>

Hoist the listxattr code from xfs_repair so that we can use it in
xfs_db.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Dave Chinner <dchinner@redhat.com>
---
 libxfs/Makefile    |    2 ++
 libxfs/listxattr.c |    2 +-
 libxfs/listxattr.h |    6 +++---
 repair/Makefile    |    2 --
 repair/pptr.c      |    2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)
 rename repair/listxattr.c => libxfs/listxattr.c (99%)
 rename repair/listxattr.h => libxfs/listxattr.h (81%)


diff --git a/libxfs/Makefile b/libxfs/Makefile
index 4e8f9a135..2f2791cae 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -23,6 +23,7 @@ HFILES = \
 	defer_item.h \
 	libxfs_io.h \
 	libxfs_api_defs.h \
+	listxattr.h \
 	init.h \
 	libxfs_priv.h \
 	linux-err.h \
@@ -69,6 +70,7 @@ CFILES = buf_mem.c \
 	defer_item.c \
 	init.c \
 	kmem.c \
+	listxattr.c \
 	logitem.c \
 	rdwr.c \
 	topology.c \
diff --git a/repair/listxattr.c b/libxfs/listxattr.c
similarity index 99%
rename from repair/listxattr.c
rename to libxfs/listxattr.c
index 2af77b7b2..bedaca678 100644
--- a/repair/listxattr.c
+++ b/libxfs/listxattr.c
@@ -6,7 +6,7 @@
 #include "libxfs.h"
 #include "libxlog.h"
 #include "libfrog/bitmap.h"
-#include "repair/listxattr.h"
+#include "listxattr.h"
 
 /* Call a function for every entry in a shortform xattr structure. */
 STATIC int
diff --git a/repair/listxattr.h b/libxfs/listxattr.h
similarity index 81%
rename from repair/listxattr.h
rename to libxfs/listxattr.h
index 2d26fce0f..cddd96af7 100644
--- a/repair/listxattr.h
+++ b/libxfs/listxattr.h
@@ -3,8 +3,8 @@
  * Copyright (c) 2022-2024 Oracle.  All Rights Reserved.
  * Author: Darrick J. Wong <djwong@kernel.org>
  */
-#ifndef __REPAIR_LISTXATTR_H__
-#define __REPAIR_LISTXATTR_H__
+#ifndef __LIBXFS_LISTXATTR_H__
+#define __LIBXFS_LISTXATTR_H__
 
 typedef int (*xattr_walk_fn)(struct xfs_inode *ip, unsigned int attr_flags,
 		const unsigned char *name, unsigned int namelen,
@@ -12,4 +12,4 @@ typedef int (*xattr_walk_fn)(struct xfs_inode *ip, unsigned int attr_flags,
 
 int xattr_walk(struct xfs_inode *ip, xattr_walk_fn attr_fn, void *priv);
 
-#endif /* __REPAIR_LISTXATTR_H__ */
+#endif /* __LIBXFS_LISTXATTR_H__ */
diff --git a/repair/Makefile b/repair/Makefile
index e7445d53e..a36a95e35 100644
--- a/repair/Makefile
+++ b/repair/Makefile
@@ -24,7 +24,6 @@ HFILES = \
 	err_protos.h \
 	globals.h \
 	incore.h \
-	listxattr.h \
 	pptr.h \
 	prefetch.h \
 	progress.h \
@@ -59,7 +58,6 @@ CFILES = \
 	incore_ext.c \
 	incore_ino.c \
 	init.c \
-	listxattr.c \
 	phase1.c \
 	phase2.c \
 	phase3.c \
diff --git a/repair/pptr.c b/repair/pptr.c
index 8ec6a51d2..cc66e6372 100644
--- a/repair/pptr.c
+++ b/repair/pptr.c
@@ -11,7 +11,7 @@
 #include "repair/globals.h"
 #include "repair/err_protos.h"
 #include "repair/slab.h"
-#include "repair/listxattr.h"
+#include "libxfs/listxattr.h"
 #include "repair/threads.h"
 #include "repair/incore.h"
 #include "repair/pptr.h"


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

end of thread, other threads:[~2024-08-06 18:20 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-30  3:10 [RFC PATCHSET] xfsprogs: filesystem properties Darrick J. Wong
2024-07-30  3:18 ` [PATCHSET v30.9 1/3] " Darrick J. Wong
2024-07-30  3:19   ` [PATCH 1/7] libfrog: support editing filesystem property sets Darrick J. Wong
2024-07-30 21:40     ` Christoph Hellwig
2024-07-30  3:20   ` [PATCH 2/7] xfs_spaceman: edit filesystem properties Darrick J. Wong
2024-07-30 21:41     ` Christoph Hellwig
2024-07-30 22:37       ` Darrick J. Wong
2024-07-31 15:41         ` Christoph Hellwig
2024-08-02  0:16           ` Dave Chinner
2024-07-30  3:20   ` [PATCH 3/7] xfs_db: improve getting and setting extended attributes Darrick J. Wong
2024-07-30 21:37     ` Christoph Hellwig
2024-07-30  3:20   ` [PATCH 4/7] libxfs: hoist listxattr from xfs_repair Darrick J. Wong
2024-07-30 21:38     ` Christoph Hellwig
2024-07-31 17:55       ` Darrick J. Wong
2024-07-30  3:21   ` [PATCH 5/7] libxfs: pass a transaction context through listxattr Darrick J. Wong
2024-07-30 21:38     ` Christoph Hellwig
2024-07-30  3:21   ` [PATCH 6/7] xfs_db: add a command to list xattrs Darrick J. Wong
2024-07-30 21:39     ` Christoph Hellwig
2024-07-30  3:21   ` [PATCH 7/7] xfs_property: add a new tool to administer fs properties Darrick J. Wong
2024-07-30 21:43     ` Christoph Hellwig
2024-07-30 22:28       ` Darrick J. Wong
2024-07-31 15:42         ` Christoph Hellwig
2024-07-31 17:56           ` Darrick J. Wong
2024-08-02  0:25     ` Dave Chinner
2024-07-30  3:19 ` [PATCHSET v30.9 2/3] xfs_scrub: control of autonomous self healing Darrick J. Wong
2024-07-30  3:21   ` [PATCH 1/3] libfrog: define a self_healing filesystem property Darrick J. Wong
2024-07-30 21:56     ` Christoph Hellwig
2024-07-30 23:51       ` Darrick J. Wong
2024-07-31 15:43         ` Christoph Hellwig
2024-07-31 17:45           ` Darrick J. Wong
2024-07-31 19:43             ` Christoph Hellwig
2024-07-30  3:22   ` [PATCH 2/3] xfs_scrub: allow sysadmin to control background scrubs Darrick J. Wong
2024-07-30  3:22   ` [PATCH 3/3] mkfs: set self_healing property Darrick J. Wong
2024-07-30  3:19 ` [PATCHSET v30.9 3/3] xfs_scrub: separate package for self healing Darrick J. Wong
2024-07-30  3:22   ` [PATCH 1/3] misc: shift install targets Darrick J. Wong
2024-07-30  3:22   ` [PATCH 2/3] xfs_scrub: use the self_healing fsproperty to select mode Darrick J. Wong
2024-07-30  3:23   ` [PATCH 3/3] debian: create a new package for automatic self-healing Darrick J. Wong
2024-07-30  3:19 ` [PATCHSET v30.9] fstests: xfs filesystem properties Darrick J. Wong
2024-07-30  3:23   ` [PATCH 1/1] xfs: functional testing for " Darrick J. Wong
2024-07-30  3:25   ` [PATCHSET v30.9] fstests: xfs " Darrick J. Wong
2024-08-02  0:29 ` [RFC PATCHSET] xfsprogs: " Dave Chinner
  -- strict thread matches above, loose matches on Subject: below --
2024-08-06 18:18 [PATCHSET v30.10 1/3] " Darrick J. Wong
2024-08-06 18:20 ` [PATCH 4/7] libxfs: hoist listxattr from xfs_repair Darrick J. Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox