All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: djwong@kernel.org
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>,
	Allison Collins <allison.henderson@oracle.com>,
	allison.henderson@oracle.com, linux-xfs@vger.kernel.org
Subject: [PATCH 23/25] xfsprogs: implement the upper half of parent pointers
Date: Thu, 16 Feb 2023 12:59:29 -0800	[thread overview]
Message-ID: <167657879213.3476112.16199141689205878747.stgit@magnolia> (raw)
In-Reply-To: <167657878885.3476112.11949206434283274332.stgit@magnolia>

From: Allison Collins <allison.henderson@oracle.com>

Add ioctl definitions to libxfs, build the necessary helpers into libfrog and
libhandle to iterate parents (and parent paths), then wire up xfs_scrub to be able
to query parent pointers from userspace.  The goal of this patch is to exercise
userspace, and is nowhere near a complete solution.  A basic xfs_io parent command
implementation replaces ... whatever that is that's there now.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Allison Collins <allison.henderson@oracle.com>
---
 include/handle.h   |    2 
 include/parent.h   |   18 ++
 io/parent.c        |  473 +++++++++++++---------------------------------------
 libfrog/paths.c    |  136 +++++++++++++++
 libfrog/paths.h    |   21 ++
 libhandle/Makefile |    2 
 libhandle/handle.c |    7 -
 libhandle/parent.c |  328 ++++++++++++++++++++++++++++++++++++
 scrub/inodes.c     |   26 +++
 scrub/inodes.h     |    2 
 10 files changed, 658 insertions(+), 357 deletions(-)
 create mode 100644 libhandle/parent.c


diff --git a/include/handle.h b/include/handle.h
index 34246f38..1f02c964 100644
--- a/include/handle.h
+++ b/include/handle.h
@@ -40,6 +40,8 @@ extern int  fssetdm_by_handle (void *__hanp, size_t __hlen,
 
 void fshandle_destroy(void);
 
+int handle_to_fsfd(void *hanp, char **path);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/parent.h b/include/parent.h
index 4d3ad51b..fb900041 100644
--- a/include/parent.h
+++ b/include/parent.h
@@ -17,4 +17,22 @@ typedef struct parent_cursor {
 	__u32	opaque[4];      /* an opaque cookie */
 } parent_cursor_t;
 
+struct path_list;
+
+typedef int (*walk_pptr_fn)(struct xfs_pptr_info *pi, struct xfs_parent_ptr *pptr,
+		void *arg);
+typedef int (*walk_ppath_fn)(const char *mntpt, struct path_list *path,
+		void *arg);
+
+#define WALK_PPTRS_ABORT	1
+int fd_walk_pptrs(int fd, walk_pptr_fn fn, void *arg);
+int handle_walk_pptrs(void *hanp, size_t hanlen, walk_pptr_fn fn, void *arg);
+
+#define WALK_PPATHS_ABORT	1
+int fd_walk_ppaths(int fd, walk_ppath_fn fn, void *arg);
+int handle_walk_ppaths(void *hanp, size_t hanlen, walk_ppath_fn fn, void *arg);
+
+int fd_to_path(int fd, char *path, size_t pathlen);
+int handle_to_path(void *hanp, size_t hlen, char *path, size_t pathlen);
+
 #endif
diff --git a/io/parent.c b/io/parent.c
index 8f63607f..e0ca29eb 100644
--- a/io/parent.c
+++ b/io/parent.c
@@ -9,363 +9,106 @@
 #include "libfrog/paths.h"
 #include "parent.h"
 #include "handle.h"
-#include "jdm.h"
 #include "init.h"
 #include "io.h"
 
-#define PARENTBUF_SZ		16384
-#define BSTATBUF_SZ		16384
-
 static cmdinfo_t parent_cmd;
-static int verbose_flag;
-static int err_status;
-static __u64 inodes_checked;
 static char *mntpt;
 
-/*
- * check out a parent entry to see if the values seem valid
- */
-static void
-check_parent_entry(struct xfs_bstat *bstatp, parent_t *parent)
-{
-	int sts;
-	char fullpath[PATH_MAX];
-	struct stat statbuf;
-	char *str;
-
-	sprintf(fullpath, _("%s%s"), mntpt, parent->p_name);
-
-	sts = lstat(fullpath, &statbuf);
-	if (sts != 0) {
-		fprintf(stderr,
-			_("inode-path for inode: %llu is incorrect - path \"%s\" non-existent\n"),
-			(unsigned long long) bstatp->bs_ino, fullpath);
-		if (verbose_flag) {
-			fprintf(stderr,
-				_("path \"%s\" does not stat for inode: %llu; err = %s\n"),
-				fullpath,
-			       (unsigned long long) bstatp->bs_ino,
-				strerror(errno));
-		}
-		err_status++;
-		return;
-	} else {
-		if (verbose_flag > 1) {
-			printf(_("path \"%s\" found\n"), fullpath);
-		}
-	}
-
-	if (statbuf.st_ino != bstatp->bs_ino) {
-		fprintf(stderr,
-			_("inode-path for inode: %llu is incorrect - wrong inode#\n"),
-		       (unsigned long long) bstatp->bs_ino);
-		if (verbose_flag) {
-			fprintf(stderr,
-				_("ino mismatch for path \"%s\" %llu vs %llu\n"),
-				fullpath,
-				(unsigned long long)statbuf.st_ino,
-				(unsigned long long)bstatp->bs_ino);
-		}
-		err_status++;
-		return;
-	} else if (verbose_flag > 1) {
-		printf(_("inode number match: %llu\n"),
-			(unsigned long long)statbuf.st_ino);
-	}
-
-	/* get parent path */
-	str = strrchr(fullpath, '/');
-	*str = '\0';
-	sts = stat(fullpath, &statbuf);
-	if (sts != 0) {
-		fprintf(stderr,
-			_("parent path \"%s\" does not stat: %s\n"),
-			fullpath,
-			strerror(errno));
-		err_status++;
-		return;
-	} else {
-		if (parent->p_ino != statbuf.st_ino) {
-			fprintf(stderr,
-				_("inode-path for inode: %llu is incorrect - wrong parent inode#\n"),
-			       (unsigned long long) bstatp->bs_ino);
-			if (verbose_flag) {
-				fprintf(stderr,
-					_("ino mismatch for path \"%s\" %llu vs %llu\n"),
-					fullpath,
-					(unsigned long long)parent->p_ino,
-					(unsigned long long)statbuf.st_ino);
-			}
-			err_status++;
-			return;
-		} else {
-			if (verbose_flag > 1) {
-			       printf(_("parent ino match for %llu\n"),
-				       (unsigned long long) parent->p_ino);
-			}
-		}
-	}
-}
-
-static void
-check_parents(parent_t *parentbuf, size_t *parentbuf_size,
-	     jdm_fshandle_t *fshandlep, struct xfs_bstat *statp)
-{
-	int error, i;
-	__u32 count;
-	parent_t *entryp;
-
-	do {
-		error = jdm_parentpaths(fshandlep, statp, parentbuf, *parentbuf_size, &count);
-
-		if (error == ERANGE) {
-			*parentbuf_size *= 2;
-			parentbuf = (parent_t *)realloc(parentbuf, *parentbuf_size);
-		} else if (error) {
-			fprintf(stderr, _("parentpaths failed for ino %llu: %s\n"),
-			       (unsigned long long) statp->bs_ino,
-				strerror(errno));
-			err_status++;
-			break;
-		}
-	} while (error == ERANGE);
-
-
-	if (count == 0) {
-		/* no links for inode - something wrong here */
-	       fprintf(stderr, _("inode-path for inode: %llu is missing\n"),
-			       (unsigned long long) statp->bs_ino);
-		err_status++;
-	}
-
-	entryp = parentbuf;
-	for (i = 0; i < count; i++) {
-		check_parent_entry(statp, entryp);
-		entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen);
-	}
-}
-
 static int
-do_bulkstat(parent_t *parentbuf, size_t *parentbuf_size,
-	    struct xfs_bstat *bstatbuf, int fsfd, jdm_fshandle_t *fshandlep)
+pptr_print(
+	struct xfs_pptr_info	*pi,
+	struct xfs_parent_ptr	*pptr,
+	void			*arg)
 {
-	__s32 buflenout;
-	__u64 lastino = 0;
-	struct xfs_bstat *p;
-	struct xfs_bstat *endp;
-	struct xfs_fsop_bulkreq bulkreq;
-	struct stat mntstat;
+	char			buf[XFS_PPTR_MAXNAMELEN + 1];
+	unsigned int		namelen = strlen((char *)pptr->xpp_name);
 
-	if (stat(mntpt, &mntstat)) {
-		fprintf(stderr, _("can't stat mount point \"%s\": %s\n"),
-			mntpt, strerror(errno));
-		return 1;
+	if (pi->pi_flags & XFS_PPTR_OFLAG_ROOT) {
+		printf(_("Root directory.\n"));
+		return 0;
 	}
 
-	bulkreq.lastip  = &lastino;
-	bulkreq.icount  = BSTATBUF_SZ;
-	bulkreq.ubuffer = (void *)bstatbuf;
-	bulkreq.ocount  = &buflenout;
-
-	while (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT, &bulkreq) == 0) {
-		if (*(bulkreq.ocount) == 0) {
-			return 0;
-		}
-		for (p = bstatbuf, endp = bstatbuf + *bulkreq.ocount; p < endp; p++) {
-
-			/* inode being modified, get synced data with iget */
-			if ( (!p->bs_nlink || !p->bs_mode) && p->bs_ino != 0 ) {
-
-				if (xfsctl(mntpt, fsfd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq) < 0) {
-				    fprintf(stderr,
-					  _("failed to get bulkstat information for inode %llu\n"),
-					 (unsigned long long) p->bs_ino);
-				    continue;
-				}
-				if (!p->bs_nlink || !p->bs_mode || !p->bs_ino) {
-				    fprintf(stderr,
-					  _("failed to get valid bulkstat information for inode %llu\n"),
-					 (unsigned long long) p->bs_ino);
-				    continue;
-				}
-			}
-
-			/* skip root */
-			if (p->bs_ino == mntstat.st_ino) {
-				continue;
-			}
-
-			if (verbose_flag > 1) {
-			       printf(_("checking inode %llu\n"),
-				       (unsigned long long) p->bs_ino);
-			}
-
-			/* print dotted progress */
-			if ((inodes_checked % 100) == 0 && verbose_flag == 1) {
-				printf("."); fflush(stdout);
-			}
-			inodes_checked++;
-
-			check_parents(parentbuf, parentbuf_size, fshandlep, p);
-		}
-
-	}/*while*/
-
-	fprintf(stderr, _("syssgi bulkstat failed: %s\n"), strerror(errno));
-	return 1;
+	memcpy(buf, pptr->xpp_name, namelen);
+	buf[namelen] = 0;
+	printf(_("p_ino    = %llu\n"), (unsigned long long)pptr->xpp_ino);
+	printf(_("p_gen    = %u\n"), (unsigned int)pptr->xpp_gen);
+	printf(_("p_reclen = %u\n"), namelen);
+	printf(_("p_name   = \"%s\"\n\n"), buf);
+	return 0;
 }
 
-static int
-parent_check(void)
+int
+print_parents(
+	struct xfs_handle	*handle)
 {
-	int fsfd;
-	jdm_fshandle_t *fshandlep;
-	parent_t *parentbuf;
-	size_t parentbuf_size = PARENTBUF_SZ;
-	struct xfs_bstat *bstatbuf;
-
-	err_status = 0;
-	inodes_checked = 0;
-
-	sync();
-
-        fsfd = file->fd;
-
-	fshandlep = jdm_getfshandle(mntpt);
-	if (fshandlep == NULL) {
-		fprintf(stderr, _("unable to open \"%s\" for jdm: %s\n"),
-		      mntpt,
-		      strerror(errno));
-		return 1;
-	}
-
-	/* allocate buffers */
-        bstatbuf = (struct xfs_bstat *)calloc(BSTATBUF_SZ, sizeof(struct xfs_bstat));
-	parentbuf = (parent_t *)malloc(parentbuf_size);
-	if (!bstatbuf || !parentbuf) {
-		fprintf(stderr, _("unable to allocate buffers: %s\n"),
-			strerror(errno));
-		err_status = 1;
-		goto out;
-	}
-
-	if (do_bulkstat(parentbuf, &parentbuf_size, bstatbuf, fsfd, fshandlep) != 0)
-		err_status++;
+	int			ret;
 
-	if (err_status > 0)
-		fprintf(stderr, _("num errors: %d\n"), err_status);
+	if (handle)
+		ret = handle_walk_pptrs(handle, sizeof(*handle), pptr_print,
+				NULL);
 	else
-		printf(_("succeeded checking %llu inodes\n"),
-			(unsigned long long) inodes_checked);
+		ret = fd_walk_pptrs(file->fd, pptr_print, NULL);
+	if (ret)
+		perror(file->name);
 
-out:
-	free(bstatbuf);
-	free(parentbuf);
-	free(fshandlep);
-	return err_status;
-}
-
-static void
-print_parent_entry(parent_t *parent, int fullpath)
-{
-       printf(_("p_ino    = %llu\n"),  (unsigned long long) parent->p_ino);
-	printf(_("p_gen    = %u\n"),	parent->p_gen);
-	printf(_("p_reclen = %u\n"),	parent->p_reclen);
-	if (fullpath)
-		printf(_("p_name   = \"%s%s\"\n"), mntpt, parent->p_name);
-	else
-		printf(_("p_name   = \"%s\"\n"), parent->p_name);
+	return 0;
 }
 
 static int
-parent_list(int fullpath)
-{
-	void *handlep = NULL;
-	size_t handlen;
-	int error, i;
-	int retval = 1;
-	__u32 count;
-	parent_t *entryp;
-	parent_t *parentbuf = NULL;
-	char *path = file->name;
-	int pb_size = PARENTBUF_SZ;
-
-	/* XXXX for linux libhandle version - to set libhandle fsfd cache */
-	{
-		void *fshandle;
-		size_t fshlen;
-
-		if (path_to_fshandle(mntpt, &fshandle, &fshlen) != 0) {
-			fprintf(stderr, _("%s: failed path_to_fshandle \"%s\": %s\n"),
-				progname, path, strerror(errno));
-			goto error;
-		}
-		free_handle(fshandle, fshlen);
+path_print(
+	const char		*mntpt,
+	struct path_list	*path,
+	void			*arg) {
+
+	char			buf[PATH_MAX];
+	size_t			len = PATH_MAX;
+	int			ret;
+
+	ret = snprintf(buf, len, "%s", mntpt);
+	if (ret != strlen(mntpt)) {
+		errno = ENOMEM;
+		return -1;
 	}
 
-	if (path_to_handle(path, &handlep, &handlen) != 0) {
-		fprintf(stderr, _("%s: path_to_handle failed for \"%s\"\n"), progname, path);
-		goto error;
-	}
-
-	do {
-		parentbuf = (parent_t *)realloc(parentbuf, pb_size);
-		if (!parentbuf) {
-			fprintf(stderr, _("%s: unable to allocate parent buffer: %s\n"),
-				progname, strerror(errno));
-			goto error;
-		}
-
-		if (fullpath) {
-			error = parentpaths_by_handle(handlep,
-						       handlen,
-						       parentbuf,
-						       pb_size,
-						       &count);
-		} else {
-			error = parents_by_handle(handlep,
-						   handlen,
-						   parentbuf,
-						   pb_size,
-						   &count);
-		}
-		if (error == ERANGE) {
-			pb_size *= 2;
-		} else if (error) {
-			fprintf(stderr, _("%s: %s call failed for \"%s\": %s\n"),
-				progname, fullpath ? "parentpaths" : "parents",
-				path, strerror(errno));
-			goto error;
-		}
-	} while (error == ERANGE);
-
-	if (count == 0) {
-		/* no links for inode - something wrong here */
-		fprintf(stderr, _("%s: inode-path is missing\n"), progname);
-		goto error;
-	}
-
-	entryp = parentbuf;
-	for (i = 0; i < count; i++) {
-		print_parent_entry(entryp, fullpath);
-		entryp = (parent_t*) (((char*)entryp) + entryp->p_reclen);
-	}
+	ret = path_list_to_string(path, buf + ret, len - ret);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
 
-	retval = 0;
-error:
-	free(handlep);
-	free(parentbuf);
-	return retval;
+int
+print_paths(
+	struct xfs_handle	*handle)
+{
+	int			ret;
+
+	if (handle)
+		ret = handle_walk_ppaths(handle, sizeof(*handle), path_print,
+				NULL);
+ 	else
+		ret = fd_walk_ppaths(file->fd, path_print, NULL);
+	if (ret)
+		perror(file->name);
+	return 0;
 }
 
 static int
-parent_f(int argc, char **argv)
+parent_f(
+	int			argc,
+	char			**argv)
 {
-	int c;
-	int listpath_flag = 0;
-	int check_flag = 0;
-	fs_path_t *fs;
-	static int tab_init;
+	struct xfs_handle	handle;
+	void			*hanp = NULL;
+	size_t			hlen;
+	struct fs_path		*fs;
+	char			*p;
+	uint64_t		ino = 0;
+	uint32_t		gen = 0;
+	int			c;
+	int			listpath_flag = 0;
+	int			ret;
+	static int		tab_init;
 
 	if (!tab_init) {
 		tab_init = 1;
@@ -380,46 +123,72 @@ parent_f(int argc, char **argv)
 	}
 	mntpt = fs->fs_dir;
 
-	verbose_flag = 0;
-
-	while ((c = getopt(argc, argv, "cpv")) != EOF) {
+	while ((c = getopt(argc, argv, "p")) != EOF) {
 		switch (c) {
-		case 'c':
-			check_flag = 1;
-			break;
 		case 'p':
 			listpath_flag = 1;
 			break;
-		case 'v':
-			verbose_flag++;
-			break;
 		default:
 			return command_usage(&parent_cmd);
 		}
 	}
 
-	if (!check_flag && !listpath_flag) /* default case */
-		exitcode = parent_list(listpath_flag);
-	else {
-		if (listpath_flag)
-			exitcode = parent_list(listpath_flag);
-		if (check_flag)
-			exitcode = parent_check();
+	/*
+	 * Always initialize the fshandle table because we need it for
+	 * the ppaths functions to work.
+	 */
+	ret = path_to_fshandle((char *)mntpt, &hanp, &hlen);
+	if (ret) {
+		perror(mntpt);
+		return 0;
+ 	}
+ 
+	if (optind + 2 == argc) {
+		ino = strtoull(argv[optind], &p, 0);
+		if (*p != '\0' || ino == 0) {
+			fprintf(stderr,
+				_("Bad inode number '%s'.\n"),
+				argv[optind]);
+			return 0;
+		}
+		gen = strtoul(argv[optind + 1], &p, 0);
+		if (*p != '\0') {
+			fprintf(stderr,
+				_("Bad generation number '%s'.\n"),
+				argv[optind + 1]);
+			return 0;
+		}
+
+		memcpy(&handle, hanp, sizeof(handle));
+		handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
+				sizeof(handle.ha_fid.fid_len);
+		handle.ha_fid.fid_pad = 0;
+		handle.ha_fid.fid_ino = ino;
+		handle.ha_fid.fid_gen = gen;
+
 	}
 
+	if (listpath_flag)
+		exitcode = print_paths(ino ? &handle : NULL);
+	else
+		exitcode = print_parents(ino ? &handle : NULL);
+
+	if (hanp)
+		free_handle(hanp, hlen);
+
 	return 0;
 }
 
 static void
 parent_help(void)
 {
-	printf(_(
+printf(_(
 "\n"
 " list the current file's parents and their filenames\n"
 "\n"
-" -c -- check the current file's file system for parent consistency\n"
-" -p -- list the current file's parents and their full paths\n"
-" -v -- verbose mode\n"
+" -p -- list the current file's paths up to the root\n"
+"\n"
+"If ino and gen are supplied, use them instead.\n"
 "\n"));
 }
 
@@ -430,9 +199,9 @@ parent_init(void)
 	parent_cmd.cfunc = parent_f;
 	parent_cmd.argmin = 0;
 	parent_cmd.argmax = -1;
-	parent_cmd.args = _("[-cpv]");
+	parent_cmd.args = _("[-p] [ino gen]");
 	parent_cmd.flags = CMD_NOMAP_OK;
-	parent_cmd.oneline = _("print or check parent inodes");
+	parent_cmd.oneline = _("print parent inodes");
 	parent_cmd.help = parent_help;
 
 	if (expert)
diff --git a/libfrog/paths.c b/libfrog/paths.c
index abb29a23..a86ae07c 100644
--- a/libfrog/paths.c
+++ b/libfrog/paths.c
@@ -15,6 +15,7 @@
 #include "paths.h"
 #include "input.h"
 #include "projects.h"
+#include "list.h"
 #include <limits.h>
 
 extern char *progname;
@@ -563,3 +564,138 @@ fs_table_insert_project_path(
 
 	return error;
 }
+
+
+/* Structured path components. */
+
+struct path_list {
+	struct list_head	p_head;
+};
+
+struct path_component {
+	struct list_head	pc_list;
+	char			*pc_fname;
+};
+
+/* Initialize a path component with a given name. */
+struct path_component *
+path_component_init(
+	const char		*name)
+{
+	struct path_component	*pc;
+
+	pc = malloc(sizeof(struct path_component));
+	if (!pc)
+		return NULL;
+	INIT_LIST_HEAD(&pc->pc_list);
+	pc->pc_fname = strdup(name);
+	if (!pc->pc_fname) {
+		free(pc);
+		return NULL;
+	}
+	return pc;
+}
+
+/* Free a path component. */
+void
+path_component_free(
+	struct path_component	*pc)
+{
+	free(pc->pc_fname);
+	free(pc);
+}
+
+/* Change a path component's filename. */
+int
+path_component_change(
+	struct path_component	*pc,
+	void			*name,
+	size_t			namelen)
+{
+	void			*p;
+
+	p = realloc(pc->pc_fname, namelen + 1);
+	if (!p)
+		return -1;
+	pc->pc_fname = p;
+	memcpy(pc->pc_fname, name, namelen);
+	pc->pc_fname[namelen] = 0;
+	return 0;
+}
+
+/* Initialize a pathname. */
+struct path_list *
+path_list_init(void)
+{
+	struct path_list	*path;
+
+	path = malloc(sizeof(struct path_list));
+	if (!path)
+		return NULL;
+	INIT_LIST_HEAD(&path->p_head);
+	return path;
+}
+
+/* Empty out a pathname. */
+void
+path_list_free(
+	struct path_list	*path)
+{
+	struct path_component	*pos;
+	struct path_component	*n;
+
+	list_for_each_entry_safe(pos, n, &path->p_head, pc_list) {
+		path_list_del_component(path, pos);
+		path_component_free(pos);
+	}
+	free(path);
+}
+
+/* Add a parent component to a pathname. */
+void
+path_list_add_parent_component(
+	struct path_list	*path,
+	struct path_component	*pc)
+{
+	list_add(&pc->pc_list, &path->p_head);
+}
+
+/* Add a component to a pathname. */
+void
+path_list_add_component(
+	struct path_list	*path,
+	struct path_component	*pc)
+{
+	list_add_tail(&pc->pc_list, &path->p_head);
+}
+
+/* Remove a component from a pathname. */
+void
+path_list_del_component(
+	struct path_list	*path,
+	struct path_component	*pc)
+{
+	list_del_init(&pc->pc_list);
+}
+
+/* Convert a pathname into a string. */
+ssize_t
+path_list_to_string(
+	struct path_list	*path,
+	char			*buf,
+	size_t			buflen)
+{
+	struct path_component	*pos;
+	ssize_t			bytes = 0;
+	int			ret;
+
+	list_for_each_entry(pos, &path->p_head, pc_list) {
+		ret = snprintf(buf, buflen, "/%s", pos->pc_fname);
+		if (ret != 1 + strlen(pos->pc_fname))
+			return -1;
+		bytes += ret;
+		buf += ret;
+		buflen -= ret;
+	}
+	return bytes;
+}
diff --git a/libfrog/paths.h b/libfrog/paths.h
index f20a2c3e..52538fb5 100644
--- a/libfrog/paths.h
+++ b/libfrog/paths.h
@@ -58,4 +58,23 @@ typedef struct fs_cursor {
 extern void fs_cursor_initialise(char *__dir, uint __flags, fs_cursor_t *__cp);
 extern fs_path_t *fs_cursor_next_entry(fs_cursor_t *__cp);
 
-#endif	/* __LIBFROG_PATH_H__ */
+/* Path information. */
+
+struct path_list;
+struct path_component;
+
+struct path_component *path_component_init(const char *name);
+void path_component_free(struct path_component *pc);
+int path_component_change(struct path_component *pc, void *name,
+		size_t namelen);
+
+struct path_list *path_list_init(void);
+void path_list_free(struct path_list *path);
+void path_list_add_parent_component(struct path_list *path,
+		struct path_component *pc);
+void path_list_add_component(struct path_list *path, struct path_component *pc);
+void path_list_del_component(struct path_list *path, struct path_component *pc);
+
+ssize_t path_list_to_string(struct path_list *path, char *buf, size_t buflen);
+
+#endif	/* __PATH_H__ */
diff --git a/libhandle/Makefile b/libhandle/Makefile
index f297a59e..cf7df67c 100644
--- a/libhandle/Makefile
+++ b/libhandle/Makefile
@@ -12,7 +12,7 @@ LT_AGE = 0
 
 LTLDFLAGS += -Wl,--version-script,libhandle.sym
 
-CFILES = handle.c jdm.c
+CFILES = handle.c jdm.c parent.c
 LSRCFILES = libhandle.sym
 
 default: ltdepend $(LTLIBRARY)
diff --git a/libhandle/handle.c b/libhandle/handle.c
index 333c2190..1e8fe9ac 100644
--- a/libhandle/handle.c
+++ b/libhandle/handle.c
@@ -29,7 +29,6 @@ typedef union {
 } comarg_t;
 
 static int obj_to_handle(char *, int, unsigned int, comarg_t, void**, size_t*);
-static int handle_to_fsfd(void *, char **);
 static char *path_to_fspath(char *path);
 
 
@@ -203,8 +202,10 @@ handle_to_fshandle(
 	return 0;
 }
 
-static int
-handle_to_fsfd(void *hanp, char **path)
+int
+handle_to_fsfd(
+	void		*hanp,
+	char		**path)
 {
 	struct fdhash	*fdhp;
 
diff --git a/libhandle/parent.c b/libhandle/parent.c
new file mode 100644
index 00000000..ebd0abd5
--- /dev/null
+++ b/libhandle/parent.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2017 Oracle.  All Rights Reserved.
+ *
+ * Author: Darrick J. Wong <darrick.wong@oracle.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+#include "platform_defs.h"
+#include "xfs.h"
+#include "xfs_arch.h"
+#include "list.h"
+#include "libfrog/paths.h"
+#include "handle.h"
+#include "parent.h"
+
+/* Allocate a buffer large enough for some parent pointer records. */
+static inline struct xfs_pptr_info *
+xfs_pptr_alloc(
+      size_t                  nr_ptrs)
+{
+      struct xfs_pptr_info    *pi;
+
+      pi = malloc(xfs_pptr_info_sizeof(nr_ptrs));
+      if (!pi)
+              return NULL;
+      memset(pi, 0, sizeof(struct xfs_pptr_info));
+      pi->pi_ptrs_size = nr_ptrs;
+      return pi;
+}
+
+/* Walk all parents of the given file handle. */
+static int
+handle_walk_parents(
+	int			fd,
+	struct xfs_handle	*handle,
+	walk_pptr_fn		fn,
+	void			*arg)
+{
+	struct xfs_pptr_info	*pi;
+	struct xfs_parent_ptr	*p;
+	unsigned int		i;
+	ssize_t			ret = -1;
+
+	pi = xfs_pptr_alloc(4);
+	if (!pi)
+		return -1;
+
+	if (handle) {
+		memcpy(&pi->pi_handle, handle, sizeof(struct xfs_handle));
+		pi->pi_flags = XFS_PPTR_IFLAG_HANDLE;
+	}
+
+	ret = ioctl(fd, XFS_IOC_GETPARENTS, pi);
+	while (!ret) {
+		if (pi->pi_flags & XFS_PPTR_OFLAG_ROOT) {
+			ret = fn(pi, NULL, arg);
+			break;
+		}
+
+		for (i = 0; i < pi->pi_ptrs_used; i++) {
+			p = xfs_ppinfo_to_pp(pi, i);
+			ret = fn(pi, p, arg);
+			if (ret)
+				goto out_pi;
+		}
+
+		if (pi->pi_flags & XFS_PPTR_OFLAG_DONE)
+			break;
+
+		ret = ioctl(fd, XFS_IOC_GETPARENTS, pi);
+	}
+
+out_pi:
+	free(pi);
+	return ret;
+}
+
+/* Walk all parent pointers of this handle. */
+int
+handle_walk_pptrs(
+	void			*hanp,
+	size_t			hlen,
+	walk_pptr_fn		fn,
+	void			*arg)
+{
+	char			*mntpt;
+	int			fd;
+
+	if (hlen != sizeof(struct xfs_handle)) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	fd = handle_to_fsfd(hanp, &mntpt);
+	if (fd < 0)
+		return -1;
+
+	return handle_walk_parents(fd, hanp, fn, arg);
+}
+
+/* Walk all parent pointers of this fd. */
+int
+fd_walk_pptrs(
+	int			fd,
+	walk_pptr_fn		fn,
+	void			*arg)
+{
+	return handle_walk_parents(fd, NULL, fn, arg);
+}
+
+struct walk_ppaths_info {
+	walk_ppath_fn			fn;
+	void				*arg;
+	char				*mntpt;
+	struct path_list		*path;
+	int				fd;
+};
+
+struct walk_ppath_level_info {
+	struct xfs_handle		newhandle;
+	struct path_component		*pc;
+	struct walk_ppaths_info		*wpi;
+};
+
+static int handle_walk_parent_paths(struct walk_ppaths_info *wpi,
+		struct xfs_handle *handle);
+
+static int
+handle_walk_parent_path_ptr(
+	struct xfs_pptr_info		*pi,
+	struct xfs_parent_ptr		*p,
+	void				*arg)
+{
+	struct walk_ppath_level_info	*wpli = arg;
+	struct walk_ppaths_info		*wpi = wpli->wpi;
+	unsigned int			i;
+	int				ret = 0;
+
+	if (pi->pi_flags & XFS_PPTR_OFLAG_ROOT)
+		return wpi->fn(wpi->mntpt, wpi->path, wpi->arg);
+
+	for (i = 0; i < pi->pi_ptrs_used; i++) {
+		p = xfs_ppinfo_to_pp(pi, i);
+		ret = path_component_change(wpli->pc, p->xpp_name,
+				strlen((char *)p->xpp_name));
+		if (ret)
+			break;
+		wpli->newhandle.ha_fid.fid_ino = p->xpp_ino;
+		wpli->newhandle.ha_fid.fid_gen = p->xpp_gen;
+		path_list_add_parent_component(wpi->path, wpli->pc);
+		ret = handle_walk_parent_paths(wpi, &wpli->newhandle);
+		path_list_del_component(wpi->path, wpli->pc);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+/*
+ * Recursively walk all parents of the given file handle; if we hit the
+ * fs root then we call the associated function with the constructed path.
+ */
+static int
+handle_walk_parent_paths(
+	struct walk_ppaths_info		*wpi,
+	struct xfs_handle		*handle)
+{
+	struct walk_ppath_level_info	*wpli;
+	int				ret;
+
+	wpli = malloc(sizeof(struct walk_ppath_level_info));
+	if (!wpli)
+		return -1;
+	wpli->pc = path_component_init("");
+	if (!wpli->pc) {
+		free(wpli);
+		return -1;
+	}
+	wpli->wpi = wpi;
+	memcpy(&wpli->newhandle, handle, sizeof(struct xfs_handle));
+
+	ret = handle_walk_parents(wpi->fd, handle, handle_walk_parent_path_ptr,
+			wpli);
+
+	path_component_free(wpli->pc);
+	free(wpli);
+	return ret;
+}
+
+/*
+ * Call the given function on all known paths from the vfs root to the inode
+ * described in the handle.
+ */
+int
+handle_walk_ppaths(
+	void			*hanp,
+	size_t			hlen,
+	walk_ppath_fn		fn,
+	void			*arg)
+{
+	struct walk_ppaths_info	wpi;
+	ssize_t			ret;
+
+	if (hlen != sizeof(struct xfs_handle)) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	wpi.fd = handle_to_fsfd(hanp, &wpi.mntpt);
+	if (wpi.fd < 0)
+		return -1;
+	wpi.path = path_list_init();
+	if (!wpi.path)
+		return -1;
+	wpi.fn = fn;
+	wpi.arg = arg;
+
+	ret = handle_walk_parent_paths(&wpi, hanp);
+	path_list_free(wpi.path);
+
+	return ret;
+}
+
+/*
+ * Call the given function on all known paths from the vfs root to the inode
+ * referred to by the file description.
+ */
+int
+fd_walk_ppaths(
+	int			fd,
+	walk_ppath_fn		fn,
+	void			*arg)
+{
+	struct walk_ppaths_info	wpi;
+	void			*hanp;
+	size_t			hlen;
+	int			fsfd;
+	int			ret;
+
+	ret = fd_to_handle(fd, &hanp, &hlen);
+	if (ret)
+		return ret;
+
+	fsfd = handle_to_fsfd(hanp, &wpi.mntpt);
+	if (fsfd < 0)
+		return -1;
+	wpi.fd = fd;
+	wpi.path = path_list_init();
+	if (!wpi.path)
+		return -1;
+	wpi.fn = fn;
+	wpi.arg = arg;
+
+	ret = handle_walk_parent_paths(&wpi, hanp);
+	path_list_free(wpi.path);
+
+	return ret;
+}
+
+struct path_walk_info {
+	char			*buf;
+	size_t			len;
+};
+
+/* Helper that stringifies the first full path that we find. */
+static int
+handle_to_path_walk(
+	const char		*mntpt,
+	struct path_list	*path,
+	void			*arg)
+{
+	struct path_walk_info	*pwi = arg;
+	int			ret;
+
+	ret = snprintf(pwi->buf, pwi->len, "%s", mntpt);
+	if (ret != strlen(mntpt)) {
+		errno = ENOMEM;
+		return -1;
+	}
+
+	ret = path_list_to_string(path, pwi->buf + ret, pwi->len - ret);
+	if (ret < 0)
+		return ret;
+
+	return WALK_PPATHS_ABORT;
+}
+
+/* Return any eligible path to this file handle. */
+int
+handle_to_path(
+	void			*hanp,
+	size_t			hlen,
+	char			*path,
+	size_t			pathlen)
+{
+	struct path_walk_info	pwi;
+
+	pwi.buf = path;
+	pwi.len = pathlen;
+	return handle_walk_ppaths(hanp, hlen, handle_to_path_walk, &pwi);
+}
+
+/* Return any eligible path to this file description. */
+int
+fd_to_path(
+	int			fd,
+	char			*path,
+	size_t			pathlen)
+{
+	struct path_walk_info	pwi;
+
+	pwi.buf = path;
+	pwi.len = pathlen;
+	return fd_walk_ppaths(fd, handle_to_path_walk, &pwi);
+}
diff --git a/scrub/inodes.c b/scrub/inodes.c
index 78f0914b..245dd713 100644
--- a/scrub/inodes.c
+++ b/scrub/inodes.c
@@ -19,6 +19,7 @@
 #include "descr.h"
 #include "libfrog/fsgeom.h"
 #include "libfrog/bulkstat.h"
+#include "parent.h"
 
 /*
  * Iterate a range of inodes.
@@ -449,3 +450,28 @@ scrub_open_handle(
 	return open_by_fshandle(handle, sizeof(*handle),
 			O_RDONLY | O_NOATIME | O_NOFOLLOW | O_NOCTTY);
 }
+
+/* Construct a description for an inode. */
+void
+xfs_scrub_ino_descr(
+	struct scrub_ctx	*ctx,
+	struct xfs_handle	*handle,
+	char			*buf,
+	size_t			buflen)
+{
+	uint64_t		ino;
+	xfs_agnumber_t		agno;
+	xfs_agino_t		agino;
+	int			ret;
+
+	ret = handle_to_path(handle, sizeof(struct xfs_handle), buf, buflen);
+	if (ret >= 0)
+		return;
+
+	ino = handle->ha_fid.fid_ino;
+	agno = ino / (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
+	agino = ino % (1ULL << (ctx->mnt.inopblog + ctx->mnt.agblklog));
+	snprintf(buf, buflen, _("inode %"PRIu64" (%u/%u)"), ino, agno,
+			agino);
+}
+
diff --git a/scrub/inodes.h b/scrub/inodes.h
index f0318045..189fa282 100644
--- a/scrub/inodes.h
+++ b/scrub/inodes.h
@@ -21,5 +21,7 @@ int scrub_scan_all_inodes(struct scrub_ctx *ctx, scrub_inode_iter_fn fn,
 		void *arg);
 
 int scrub_open_handle(struct xfs_handle *handle);
+void xfs_scrub_ino_descr(struct scrub_ctx *ctx, struct xfs_handle *handle,
+		char *buf, size_t buflen);
 
 #endif /* XFS_SCRUB_INODES_H_ */


  parent reply	other threads:[~2023-02-16 20:59 UTC|newest]

Thread overview: 227+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-16 20:06 [RFC DELUGE v9r2d1] xfs: Parent Pointers Darrick J. Wong
2023-02-16 20:26 ` [PATCHSET v9r2d1 00/28] " Darrick J. Wong
2023-02-16 20:32   ` [PATCH 01/28] xfs: Add new name to attri/d Darrick J. Wong
2023-02-16 20:33   ` [PATCH 02/28] xfs: Increase XFS_DEFER_OPS_NR_INODES to 5 Darrick J. Wong
2023-02-16 20:33   ` [PATCH 03/28] xfs: Increase XFS_QM_TRANS_MAXDQS " Darrick J. Wong
2023-02-16 20:33   ` [PATCH 04/28] xfs: Hold inode locks in xfs_ialloc Darrick J. Wong
2023-02-16 20:33   ` [PATCH 05/28] xfs: Hold inode locks in xfs_trans_alloc_dir Darrick J. Wong
2023-02-16 20:34   ` [PATCH 06/28] xfs: Hold inode locks in xfs_rename Darrick J. Wong
2023-02-16 20:34   ` [PATCH 07/28] xfs: Expose init_xattrs in xfs_create_tmpfile Darrick J. Wong
2023-02-16 20:34   ` [PATCH 08/28] xfs: get directory offset when adding directory name Darrick J. Wong
2023-02-16 20:35   ` [PATCH 09/28] xfs: get directory offset when removing " Darrick J. Wong
2023-02-16 20:35   ` [PATCH 10/28] xfs: get directory offset when replacing a " Darrick J. Wong
2023-02-16 20:35   ` [PATCH 11/28] xfs: add parent pointer support to attribute code Darrick J. Wong
2023-02-16 20:35   ` [PATCH 12/28] xfs: define parent pointer xattr format Darrick J. Wong
2023-02-16 20:36   ` [PATCH 13/28] xfs: Add xfs_verify_pptr Darrick J. Wong
2023-02-16 20:36   ` [PATCH 14/28] xfs: extend transaction reservations for parent attributes Darrick J. Wong
2023-02-16 20:36   ` [PATCH 15/28] xfs: parent pointer attribute creation Darrick J. Wong
2023-02-16 20:36   ` [PATCH 16/28] xfs: add parent attributes to link Darrick J. Wong
2023-02-16 20:37   ` [PATCH 17/28] xfs: add parent attributes to symlink Darrick J. Wong
2023-02-16 20:37   ` [PATCH 18/28] xfs: remove parent pointers in unlink Darrick J. Wong
2023-02-16 20:37   ` [PATCH 19/28] xfs: Indent xfs_rename Darrick J. Wong
2023-02-16 20:37   ` [PATCH 20/28] xfs: Add parent pointers to rename Darrick J. Wong
2023-02-16 20:38   ` [PATCH 21/28] xfs: Add parent pointers to xfs_cross_rename Darrick J. Wong
2023-02-16 20:38   ` [PATCH 22/28] xfs: Add the parent pointer support to the superblock version 5 Darrick J. Wong
2023-02-16 20:38   ` [PATCH 23/28] xfs: Add helper function xfs_attr_list_context_init Darrick J. Wong
2023-02-16 20:38   ` [PATCH 24/28] xfs: Filter XFS_ATTR_PARENT for getfattr Darrick J. Wong
2023-02-16 20:39   ` [PATCH 25/28] xfs: Add parent pointer ioctl Darrick J. Wong
2023-02-16 20:39   ` [PATCH 26/28] xfs: fix unit conversion error in xfs_log_calc_max_attrsetm_res Darrick J. Wong
2023-02-16 20:39   ` [PATCH 27/28] xfs: drop compatibility minimum log size computations for reflink Darrick J. Wong
2023-02-16 20:39   ` [PATCH 28/28] xfs: add xfs_trans_mod_sb tracing Darrick J. Wong
2023-02-16 20:26 ` [PATCHSET v9r2d1 0/3] xfs: bug fixes for parent pointers Darrick J. Wong
2023-02-16 20:40   ` [PATCH 1/3] xfs: directory lookups should return diroffsets too Darrick J. Wong
2023-02-16 20:40   ` [PATCH 2/3] xfs: move/add parent pointer validators to xfs_parent Darrick J. Wong
2023-02-16 20:40   ` [PATCH 3/3] xfs: don't remove the attr fork when parent pointers are enabled Darrick J. Wong
2023-02-16 20:26 ` [PATCHSET v9r2d1 0/4] xfs: rework the GETPARENTS ioctl Darrick J. Wong
2023-02-16 20:40   ` [PATCH 1/4] xfs: fix multiple problems when doing getparents by handle Darrick J. Wong
2023-02-16 20:41   ` [PATCH 2/4] xfs: use kvalloc for the parent pointer info buffer Darrick J. Wong
2023-02-16 20:41   ` [PATCH 3/4] xfs: pass the attr value to put_listent when possible Darrick J. Wong
2023-02-16 20:41   ` [PATCH 4/4] xfs: replace the XFS_IOC_GETPARENTS backend Darrick J. Wong
2023-02-16 20:27 ` [PATCHSET v9r2d1 00/23] xfs: online fsck support patches Darrick J. Wong
2023-02-16 20:42   ` [PATCH 01/23] xfs: manage inode DONTCACHE status at irele time Darrick J. Wong
2023-02-16 20:42   ` [PATCH 02/23] xfs: make checking directory dotdot entries more reliable Darrick J. Wong
2023-02-16 20:42   ` [PATCH 03/23] xfs: xfs_iget in the directory scrubber needs to use UNTRUSTED Darrick J. Wong
2023-02-16 20:42   ` [PATCH 04/23] xfs: always check the existence of a dirent's child inode Darrick J. Wong
2023-02-16 20:43   ` [PATCH 05/23] xfs: remove the for_each_xbitmap_ helpers Darrick J. Wong
2023-02-16 20:43   ` [PATCH 06/23] xfs: drop the _safe behavior from the xbitmap foreach macro Darrick J. Wong
2023-02-16 20:43   ` [PATCH 07/23] xfs: convert xbitmap to interval tree Darrick J. Wong
2023-02-16 20:43   ` [PATCH 08/23] xfs: port xbitmap_test Darrick J. Wong
2023-02-16 20:44   ` [PATCH 09/23] xfs: ignore stale buffers when scanning the buffer cache Darrick J. Wong
2023-02-16 20:44   ` [PATCH 10/23] xfs: create a big array data structure Darrick J. Wong
2023-02-16 20:44   ` [PATCH 11/23] xfs: wrap ilock/iunlock operations on sc->ip Darrick J. Wong
2023-02-16 20:44   ` [PATCH 12/23] xfs: port scrub inode scan from djwong-dev Darrick J. Wong
2023-02-16 20:45   ` [PATCH 13/23] xfs: allow scrub to hook metadata updates in other writers Darrick J. Wong
2023-02-16 20:45   ` [PATCH 14/23] xfs: allow blocking notifier chains with filesystem hooks Darrick J. Wong
2023-02-16 20:45   ` [PATCH 15/23] xfs: streamline the directory iteration code for scrub Darrick J. Wong
2023-02-16 20:45   ` [PATCH 16/23] xfs: track file link count updates during live nlinks fsck Darrick J. Wong
2023-02-16 20:46   ` [PATCH 17/23] xfs: connect in-memory btrees to xfiles Darrick J. Wong
2023-02-16 20:46   ` [PATCH 18/23] xfs: create temporary files and directories for online repair Darrick J. Wong
2023-02-16 20:46   ` [PATCH 19/23] xfs: hide private inodes from bulkstat and handle functions Darrick J. Wong
2023-02-16 20:46   ` [PATCH 20/23] xfs: create a blob array data structure Darrick J. Wong
2023-02-16 20:47   ` [PATCH 21/23] xfs: repair extended attributes Darrick J. Wong
2023-02-16 20:47   ` [PATCH 22/23] xfs: online repair of directories Darrick J. Wong
2023-02-16 20:47   ` [PATCH 23/23] xfs: create an xattr iteration function for scrub Darrick J. Wong
2023-02-16 20:27 ` [PATCHSET v9r2d1 0/7] xfs: online repair of directories Darrick J. Wong
2023-02-16 20:48   ` [PATCH 1/7] xfs: pass directory offsets as part of the dirent hook data Darrick J. Wong
2023-02-16 20:48   ` [PATCH 2/7] xfs: pass diroffset back from xchk_dir_lookup Darrick J. Wong
2023-02-16 20:48   ` [PATCH 3/7] xfs: shorten parent pointer function names Darrick J. Wong
2023-02-16 20:48   ` [PATCH 4/7] xfs: rearrange bits of the parent pointer apis for fsck Darrick J. Wong
2023-02-16 20:49   ` [PATCH 5/7] xfs: reconstruct directories from parent pointers Darrick J. Wong
2023-02-16 20:49   ` [PATCH 6/7] xfs: add hooks to do directory updates Darrick J. Wong
2023-02-16 20:49   ` [PATCH 7/7] xfs: compare generated and existing dirents Darrick J. Wong
2023-02-16 20:27 ` [PATCHSET v9r2d1 0/2] xfs: online checking of parent pointers Darrick J. Wong
2023-02-16 20:49   ` [PATCH 1/2] xfs: scrub " Darrick J. Wong
2023-02-16 20:50   ` [PATCH 2/2] xfs: deferred scrub of " Darrick J. Wong
2023-02-16 20:27 ` [PATCHSET v9r2d1 0/3] xfs: online checking " Darrick J. Wong
2023-02-16 20:50   ` [PATCH 1/3] xfs: repair parent pointers by scanning directories Darrick J. Wong
2023-02-16 20:50   ` [PATCH 2/3] xfs: repair parent pointers with live scan hooks Darrick J. Wong
2023-02-16 20:50   ` [PATCH 3/3] xfs: compare generated and existing parent pointers Darrick J. Wong
2023-02-16 20:28 ` [PATCHSET v9r2d1 0/2] xfs: online checking of directories Darrick J. Wong
2023-02-16 20:51   ` [PATCH 1/2] xfs: check dirents have parent pointers Darrick J. Wong
2023-02-16 20:51   ` [PATCH 2/2] xfs: deferred scrub of dirents Darrick J. Wong
2023-02-16 20:28 ` [PATCHSET v9r2d1 0/5] xfs: encode parent pointer name in xattr key Darrick J. Wong
2023-02-16 20:51   ` [PATCH 1/5] xfs: load secure hash algorithm for parent pointers Darrick J. Wong
2023-02-16 20:51   ` [PATCH 2/5] xfs: replace parent pointer diroffset with sha512 hash of name Darrick J. Wong
2023-02-16 20:52   ` [PATCH 3/5] xfs: skip the sha512 namehash when possible Darrick J. Wong
2023-02-16 20:52   ` [PATCH 4/5] xfs: make the ondisk parent pointer record a flex array Darrick J. Wong
2023-02-16 20:52   ` [PATCH 5/5] xfs: use parent pointer xattr space more efficiently Darrick J. Wong
2023-02-18  8:12   ` [PATCHSET v9r2d1 0/5] xfs: encode parent pointer name in xattr key Amir Goldstein
2023-02-24  2:58     ` Darrick J. Wong
2023-03-03 16:43   ` Darrick J. Wong
2023-03-03 17:11   ` [PATCHSET v9r2d1.1 00/13] xfs: remove parent pointer hashing Darrick J. Wong
2023-03-03 17:11     ` [PATCH 01/13] xfs: make xfs_attr_set require XFS_DA_OP_REMOVE Darrick J. Wong
2023-03-03 17:11     ` [PATCH 02/13] xfs: allow xattr matching on value for local/sf attrs Darrick J. Wong
2023-03-03 17:11     ` [PATCH 03/13] xfs: preserve VLOOKUP in xfs_attr_set Darrick J. Wong
2023-03-03 17:11     ` [PATCH 04/13] xfs: log VLOOKUP xattr removal operations Darrick J. Wong
2023-03-03 17:11     ` [PATCH 05/13] xfs: log VLOOKUP xattr setting operations Darrick J. Wong
2023-03-03 17:11     ` [PATCH 06/13] xfs: refactor extracting attri ops from alfi_op_flags Darrick J. Wong
2023-03-03 17:11     ` [PATCH 07/13] xfs: overlay alfi_nname_len atop alfi_name_len for NVREPLACE Darrick J. Wong
2023-03-03 17:12     ` [PATCH 08/13] xfs: rename nname to newname Darrick J. Wong
2023-03-03 17:12     ` [PATCH 09/13] xfs: log VLOOKUP xattr nvreplace operations Darrick J. Wong
2023-03-03 17:12     ` [PATCH 10/13] xfs: log old xattr values for NVREPLACEXXX operations Darrick J. Wong
2023-03-03 17:12     ` [PATCH 11/13] xfs: use VLOOKUP mode to avoid hashing parent pointer names Darrick J. Wong
2023-03-03 17:12     ` [PATCH 12/13] xfs: turn NVREPLACEXXX into NVREPLACE Darrick J. Wong
2023-03-03 17:12     ` [PATCH 13/13] xfs: revert "load secure hash algorithm for parent pointers" Darrick J. Wong
2023-02-16 20:28 ` [PATCHSET v9r2d1 0/3] xfs: use flex arrays for XFS_IOC_GETPARENTS Darrick J. Wong
2023-02-16 20:52   ` [PATCH 1/3] xfs: rename xfs_pptr_info to xfs_getparents Darrick J. Wong
2023-02-16 20:53   ` [PATCH 2/3] xfs: rename xfs_parent_ptr Darrick J. Wong
2023-02-16 20:53   ` [PATCH 3/3] xfs: convert GETPARENTS structures to flex arrays Darrick J. Wong
2023-02-16 20:29 ` [PATCHSET v9r2d1 00/25] xfsprogs: Parent Pointers Darrick J. Wong
2023-02-16 20:53   ` [PATCH 01/25] xfsprogs: Fix default superblock attr bits Darrick J. Wong
2023-02-16 20:54   ` [PATCH 02/25] xfsprogs: Add new name to attri/d Darrick J. Wong
2023-02-16 20:54   ` [PATCH 03/25] xfsprogs: Increase XFS_DEFER_OPS_NR_INODES to 5 Darrick J. Wong
2023-02-16 20:54   ` [PATCH 04/25] xfsprogs: get directory offset when adding directory name Darrick J. Wong
2023-02-16 20:54   ` [PATCH 05/25] xfsprogs: get directory offset when removing " Darrick J. Wong
2023-02-16 20:55   ` [PATCH 06/25] xfsprogs: get directory offset when replacing a " Darrick J. Wong
2023-02-16 20:55   ` [PATCH 07/25] xfsprogs: add parent pointer support to attribute code Darrick J. Wong
2023-02-16 20:55   ` [PATCH 08/25] xfsprogs: define parent pointer xattr format Darrick J. Wong
2023-02-16 20:55   ` [PATCH 09/25] xfsprogs: Add xfs_verify_pptr Darrick J. Wong
2023-02-16 20:56   ` [PATCH 10/25] xfsprogs: extend transaction reservations for parent attributes Darrick J. Wong
2023-02-16 20:56   ` [PATCH 11/25] xfsprogs: parent pointer attribute creation Darrick J. Wong
2023-02-16 20:56   ` [PATCH 12/25] xfsprogs: add parent attributes to link Darrick J. Wong
2023-02-16 20:56   ` [PATCH 13/25] xfsprogs: add parent attributes to symlink Darrick J. Wong
2023-02-16 20:57   ` [PATCH 14/25] xfsprogs: remove parent pointers in unlink Darrick J. Wong
2023-02-16 20:57   ` [PATCH 15/25] xfsprogs: Add parent pointers to rename Darrick J. Wong
2023-02-16 20:57   ` [PATCH 16/25] xfsprogs: Add the parent pointer support to the superblock version 5 Darrick J. Wong
2023-02-16 20:57   ` [PATCH 17/25] xfsprogs: Add parent pointer ioctl Darrick J. Wong
2023-02-16 20:58   ` [PATCH 18/25] xfsprogs: fix unit conversion error in xfs_log_calc_max_attrsetm_res Darrick J. Wong
2023-02-16 20:58   ` [PATCH 19/25] xfsprogs: drop compatibility minimum log size computations for reflink Darrick J. Wong
2023-02-16 20:58   ` [PATCH 20/25] xfsprogs: Add parent pointer flag to cmd Darrick J. Wong
2023-02-16 20:58   ` [PATCH 21/25] xfsprogs: Print pptrs in ATTRI items Darrick J. Wong
2023-02-16 20:59   ` [PATCH 22/25] xfs_db: report parent bit on xattrs Darrick J. Wong
2023-02-16 20:59   ` Darrick J. Wong [this message]
2023-02-16 20:59   ` [PATCH 24/25] xfsprogs: Add parent pointers during protofile creation Darrick J. Wong
2023-02-16 21:00   ` [PATCH 25/25] xfsprogs: Add i, n and f flags to parent command Darrick J. Wong
2023-02-16 20:29 ` [PATCHSET v9r2d1 0/6] xfsprogs: bug fixes before parent pointers Darrick J. Wong
2023-02-16 21:00   ` [PATCH 1/6] libxfs: initialize the slab cache for parent defer items Darrick J. Wong
2023-02-16 21:00   ` [PATCH 2/6] xfs: directory lookups should return diroffsets too Darrick J. Wong
2023-02-16 21:00   ` [PATCH 3/6] xfs: move/add parent pointer validators to xfs_parent Darrick J. Wong
2023-02-16 21:01   ` [PATCH 4/6] xfs: don't remove the attr fork when parent pointers are enabled Darrick J. Wong
2023-02-16 21:01   ` [PATCH 5/6] xfs: pass the attr value to put_listent when possible Darrick J. Wong
2023-02-16 21:01   ` [PATCH 6/6] xfs: replace the XFS_IOC_GETPARENTS backend Darrick J. Wong
2023-02-16 20:29 ` [PATCHSET v9r2d1 0/6] xfsprogs: tool fixes for parent pointers Darrick J. Wong
2023-02-16 21:01   ` [PATCH 1/6] xfs_scrub: don't report media errors for space with unknowable owner Darrick J. Wong
2023-02-16 21:02   ` [PATCH 2/6] mkfs: fix libxfs api misuse Darrick J. Wong
2023-02-16 21:02   ` [PATCH 3/6] libxfs: create new files with attr forks if necessary Darrick J. Wong
2023-02-16 21:02   ` [PATCH 4/6] mkfs: fix subdir parent pointer creation Darrick J. Wong
2023-02-16 21:02   ` [PATCH 5/6] xfs_db: report parent pointer keys Darrick J. Wong
2023-02-16 21:03   ` [PATCH 6/6] xfs_db: obfuscate dirent and pptr names consistently Darrick J. Wong
2023-02-16 20:29 ` [PATCHSET v9r2d1 00/10] xfsprogs: actually use getparent ioctl Darrick J. Wong
2023-02-16 21:03   ` [PATCH 01/10] xfs_scrub: revert unnecessary code from "implement the upper half of parent pointers" Darrick J. Wong
2023-02-16 21:03   ` [PATCH 02/10] xfs_io: print path in path_print Darrick J. Wong
2023-02-16 21:03   ` [PATCH 03/10] xfs_io: move parent pointer filtering and formatting flags out of libhandle Darrick J. Wong
2023-02-16 21:04   ` [PATCH 04/10] libfrog: remove all the parent pointer code from libhandle Darrick J. Wong
2023-02-16 21:04   ` [PATCH 05/10] libfrog: fix indenting errors in xfss_pptr_alloc Darrick J. Wong
2023-02-16 21:04   ` [PATCH 06/10] libfrog: return positive errno in pptrs.c Darrick J. Wong
2023-02-16 21:04   ` [PATCH 07/10] libfrog: only walk one parent pointer at a time in handle_walk_parent_path_ptr Darrick J. Wong
2023-02-16 21:05   ` [PATCH 08/10] libfrog: trim trailing slashes when printing pptr paths Darrick J. Wong
2023-02-16 21:05   ` [PATCH 09/10] xfs_io: parent command is not experts-only Darrick J. Wong
2023-02-16 21:05   ` [PATCH 10/10] xfs_scrub: use parent pointers when possible to report file operations Darrick J. Wong
2023-02-16 20:30 ` [PATCHSET v9r2d1 0/4] xfsprogs: offline fsck support patches Darrick J. Wong
2023-02-16 21:06   ` [PATCH 1/4] libxfs: add xfile support Darrick J. Wong
2023-02-16 21:06   ` [PATCH 2/4] xfs: track file link count updates during live nlinks fsck Darrick J. Wong
2023-02-16 21:06   ` [PATCH 3/4] xfs: create a blob array data structure Darrick J. Wong
2023-02-16 21:06   ` [PATCH 4/4] libxfs: export attr3_leaf_hdr_from_disk via libxfs_api_defs.h Darrick J. Wong
2023-02-16 20:30 ` [PATCHSET v9r2d1 0/3] xfsprogs: online repair of directories Darrick J. Wong
2023-02-16 21:07   ` [PATCH 1/3] xfs: shorten parent pointer function names Darrick J. Wong
2023-02-16 21:07   ` [PATCH 2/3] xfs: rearrange bits of the parent pointer apis for fsck Darrick J. Wong
2023-02-16 21:07   ` [PATCH 3/3] xfs: add hooks to do directory updates Darrick J. Wong
2023-02-16 20:30 ` [PATCHSET v9r2d1 0/1] xfsprogs: online checking of parent pointers Darrick J. Wong
2023-02-16 21:07   ` [PATCH 1/1] xfs: deferred scrub " Darrick J. Wong
2023-02-16 20:30 ` [PATCHSET v9r2d1 0/2] xfsprogs: online checking " Darrick J. Wong
2023-02-16 21:08   ` [PATCH 1/2] xfs: repair parent pointers by scanning directories Darrick J. Wong
2023-02-16 21:08   ` [PATCH 2/2] xfs: repair parent pointers with live scan hooks Darrick J. Wong
2023-02-16 20:31 ` [PATCHSET v9r2d1 0/8] xfs_repair: support parent pointers Darrick J. Wong
2023-02-16 21:08   ` [PATCH 1/8] xfs_repair: build a parent pointer index Darrick J. Wong
2023-02-16 21:08   ` [PATCH 2/8] xfs_repair: check parent pointers Darrick J. Wong
2023-02-16 21:09   ` [PATCH 3/8] xfs_repair: dump garbage parent pointer attributes Darrick J. Wong
2023-02-16 21:09   ` [PATCH 4/8] xfs_repair: update ondisk parent pointer records Darrick J. Wong
2023-02-16 21:09   ` [PATCH 5/8] xfs_repair: wipe ondisk parent pointers when there are none Darrick J. Wong
2023-02-16 21:09   ` [PATCH 6/8] xfs_repair: move the global dirent name store to a separate object Darrick J. Wong
2023-02-16 21:10   ` [PATCH 7/8] xfs_repair: deduplicate strings stored in string blob Darrick J. Wong
2023-02-16 21:10   ` [PATCH 8/8] xfs_repair: try to reuse nameblob names for file pptr scan names Darrick J. Wong
2023-02-16 20:31 ` [PATCHSET v9r2d1 0/6] xfsprogs: encode parent pointer name in xattr key Darrick J. Wong
2023-02-16 21:10   ` [PATCH 1/6] libfrog: support the sha512 hash algorithm Darrick J. Wong
2023-02-16 21:10   ` [PATCH 2/6] xfs: replace parent pointer diroffset with sha512 hash of name Darrick J. Wong
2023-02-16 21:11   ` [PATCH 3/6] xfs_logprint: decode parent pointers fully Darrick J. Wong
2023-02-16 21:11   ` [PATCH 4/6] xfs: skip the sha512 namehash when possible Darrick J. Wong
2023-02-16 21:11   ` [PATCH 5/6] xfs: make the ondisk parent pointer record a flex array Darrick J. Wong
2023-02-16 21:12   ` [PATCH 6/6] xfs: use parent pointer xattr space more efficiently Darrick J. Wong
2023-02-16 20:31 ` [PATCHSET v9r2d1 0/3] xfsprogs: use flex arrays for XFS_IOC_GETPARENTS Darrick J. Wong
2023-02-16 21:12   ` [PATCH 1/3] xfs: rename xfs_pptr_info to xfs_getparents Darrick J. Wong
2023-02-16 21:12   ` [PATCH 2/3] xfs: rename xfs_parent_ptr Darrick J. Wong
2023-02-16 21:12   ` [PATCH 3/3] xfs: convert GETPARENTS structures to flex arrays Darrick J. Wong
2023-02-16 20:31 ` [PATCHSET v9r2d1 0/3] xfsprogs: turn on all available features Darrick J. Wong
2023-02-16 21:13   ` [PATCH 1/3] mkfs: enable large extent counts by default Darrick J. Wong
2023-02-16 21:13   ` [PATCH 2/3] mkfs: enable reverse mapping " Darrick J. Wong
2023-02-16 21:13   ` [PATCH 3/3] mkfs: enable parent pointers " Darrick J. Wong
2023-02-16 20:32 ` [PATCHSET 00/14] fstests: adjust tests for xfs parent pointers Darrick J. Wong
2023-02-16 21:13   ` [PATCH 01/14] xfs/122: update for " Darrick J. Wong
2023-02-16 21:14   ` [PATCH 02/14] populate: create hardlinks " Darrick J. Wong
2023-02-16 21:14   ` [PATCH 03/14] xfs/021: adapt golden output files " Darrick J. Wong
2023-02-16 21:14   ` [PATCH 04/14] generic/050: adapt " Darrick J. Wong
2023-02-16 21:14   ` [PATCH 05/14] xfs/018: disable parent pointers for this test Darrick J. Wong
2023-02-16 21:15   ` [PATCH 06/14] xfs/306: fix formatting failures with parent pointers Darrick J. Wong
2023-02-16 21:15   ` [PATCH 07/14] common: add helpers for parent pointer tests Darrick J. Wong
2023-02-16 21:15   ` [PATCH 08/14] xfs: add parent pointer test Darrick J. Wong
2023-02-16 21:15   ` [PATCH 09/14] xfs: add multi link " Darrick J. Wong
2023-02-16 21:16   ` [PATCH 10/14] xfs: add parent pointer inject test Darrick J. Wong
2023-02-16 21:16   ` [PATCH 11/14] common/parent: add license and copyright Darrick J. Wong
2023-02-16 21:16   ` [PATCH 12/14] common/parent: don't _fail on missing parent pointer components Darrick J. Wong
2023-02-16 21:16   ` [PATCH 13/14] common/parent: check xfs_io parent command paths Darrick J. Wong
2023-02-16 21:17   ` [PATCH 14/14] xfs/851: test xfs_io parent -p too Darrick J. Wong
2023-02-16 20:32 ` [PATCHSET v9r2 0/4] fstests: encode parent pointer name in xattr key Darrick J. Wong
2023-02-16 21:17   ` [PATCH 1/4] misc: adjust for parent pointers with namehashes Darrick J. Wong
2023-02-16 21:17   ` [PATCH 2/4] xfs/021: adjust for short parent pointers with hashes Darrick J. Wong
2023-02-16 21:18   ` [PATCH 3/4] xfs/242: fix _filter_bmap for xfs_io bmap that does rt file properly Darrick J. Wong
2023-02-16 21:18   ` [PATCH 4/4] xfs/021: adjust for short valuelens Darrick J. Wong
2023-02-16 20:32 ` [PATCHSET v9r2 0/1] fstests: use flex arrays for XFS_IOC_GETPARENTS Darrick J. Wong
2023-02-16 21:18   ` [PATCH 1/1] xfs/122: adjust for flex-array XFS_IOC_GETPARENTS ioctl Darrick J. Wong
2023-02-17 20:02 ` [RFC DELUGE v9r2d1] xfs: Parent Pointers Allison Henderson
2023-02-24  2:51   ` Darrick J. Wong
2023-02-24  7:24     ` Amir Goldstein
2023-02-25  1:58       ` Darrick J. Wong
2023-02-25  7:34     ` Allison Henderson
2023-03-01  1:24       ` Darrick J. Wong
2023-03-08 22:47         ` Allison Henderson
2023-03-14  2:20           ` Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=167657879213.3476112.16199141689205878747.stgit@magnolia \
    --to=djwong@kernel.org \
    --cc=allison.henderson@oracle.com \
    --cc=darrick.wong@oracle.com \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.